1+ using Duende . IdentityServer ;
2+ using Duende . IdentityServer . Events ;
3+ using Duende . IdentityServer . Models ;
4+ using Duende . IdentityServer . Services ;
5+ using Duende . IdentityServer . Stores ;
6+ using Duende . IdentityServer . Test ;
7+ using Microsoft . AspNetCore . Authentication ;
8+ using Microsoft . AspNetCore . Authorization ;
9+ using Microsoft . AspNetCore . Mvc ;
10+ using Microsoft . AspNetCore . Mvc . RazorPages ;
11+
12+ namespace IdentityServerHost . Pages . Create ;
13+
14+ [ SecurityHeaders ]
15+ [ AllowAnonymous ]
16+ public class Index : PageModel
17+ {
18+ private readonly TestUserStore _users ;
19+ private readonly IIdentityServerInteractionService _interaction ;
20+
21+ [ BindProperty ]
22+ public InputModel Input { get ; set ; }
23+
24+ public Index (
25+ IIdentityServerInteractionService interaction ,
26+ TestUserStore users = null )
27+ {
28+ // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)
29+ _users = users ?? throw new Exception ( "Please call 'AddTestUsers(TestUsers.Users)' on the IIdentityServerBuilder in Startup or remove the TestUserStore from the AccountController." ) ;
30+
31+ _interaction = interaction ;
32+ }
33+
34+ public IActionResult OnGet ( string returnUrl )
35+ {
36+ Input = new InputModel { ReturnUrl = returnUrl } ;
37+ return Page ( ) ;
38+ }
39+
40+ public async Task < IActionResult > OnPost ( )
41+ {
42+ // check if we are in the context of an authorization request
43+ var context = await _interaction . GetAuthorizationContextAsync ( Input . ReturnUrl ) ;
44+
45+ // the user clicked the "cancel" button
46+ if ( Input . Button != "create" )
47+ {
48+ if ( context != null )
49+ {
50+ // if the user cancels, send a result back into IdentityServer as if they
51+ // denied the consent (even if this client does not require consent).
52+ // this will send back an access denied OIDC error response to the client.
53+ await _interaction . DenyAuthorizationAsync ( context , AuthorizationError . AccessDenied ) ;
54+
55+ // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
56+ if ( context . IsNativeClient ( ) )
57+ {
58+ // The client is native, so this change in how to
59+ // return the response is for better UX for the end user.
60+ return this . LoadingPage ( Input . ReturnUrl ) ;
61+ }
62+
63+ return Redirect ( Input . ReturnUrl ) ;
64+ }
65+ else
66+ {
67+ // since we don't have a valid context, then we just go back to the home page
68+ return Redirect ( "~/" ) ;
69+ }
70+ }
71+
72+ if ( _users . FindByUsername ( Input . Username ) != null )
73+ {
74+ ModelState . AddModelError ( "Input.Username" , "Invalid username" ) ;
75+ }
76+
77+ if ( ModelState . IsValid )
78+ {
79+ var user = _users . CreateUser ( Input . Username , Input . Password , Input . Name , Input . Email ) ;
80+
81+ // issue authentication cookie with subject ID and username
82+ var isuser = new IdentityServerUser ( user . SubjectId )
83+ {
84+ DisplayName = user . Username
85+ } ;
86+
87+ await HttpContext . SignInAsync ( isuser ) ;
88+
89+ if ( context != null )
90+ {
91+ if ( context . IsNativeClient ( ) )
92+ {
93+ // The client is native, so this change in how to
94+ // return the response is for better UX for the end user.
95+ return this . LoadingPage ( Input . ReturnUrl ) ;
96+ }
97+
98+ // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
99+ return Redirect ( Input . ReturnUrl ) ;
100+ }
101+
102+ // request for a local page
103+ if ( Url . IsLocalUrl ( Input . ReturnUrl ) )
104+ {
105+ return Redirect ( Input . ReturnUrl ) ;
106+ }
107+ else if ( string . IsNullOrEmpty ( Input . ReturnUrl ) )
108+ {
109+ return Redirect ( "~/" ) ;
110+ }
111+ else
112+ {
113+ // user might have clicked on a malicious link - should be logged
114+ throw new Exception ( "invalid return URL" ) ;
115+ }
116+ }
117+
118+ return Page ( ) ;
119+ }
120+ }
0 commit comments