88using Microsoft . AspNetCore . Hosting ;
99using Microsoft . AspNetCore . Http ;
1010using Microsoft . AspNetCore . Routing ;
11+ using Microsoft . Extensions . Configuration ;
1112using Microsoft . Extensions . DependencyInjection ;
1213using Microsoft . Extensions . Hosting ;
1314using Microsoft . IdentityModel . Tokens ;
@@ -17,11 +18,17 @@ namespace Microsoft.SCIM.WebHostSample
1718{
1819 public class Startup
1920 {
21+ private readonly IWebHostEnvironment _env ;
22+ private readonly IConfiguration _configuration ;
23+
2024 public IMonitor MonitoringBehavior { get ; set ; }
2125 public IProvider ProviderBehavior { get ; set ; }
2226
23- public Startup ( )
27+ public Startup ( IWebHostEnvironment env , IConfiguration configuration )
2428 {
29+ this . _env = env ;
30+ this . _configuration = configuration ;
31+
2532 this . MonitoringBehavior = new ConsoleMonitor ( ) ;
2633 this . ProviderBehavior = new InMemoryProvider ( ) ;
2734 }
@@ -30,26 +37,57 @@ public Startup()
3037 // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
3138 public void ConfigureServices ( IServiceCollection services )
3239 {
33- services . AddAuthentication ( options =>
40+ if ( _env . IsDevelopment ( ) )
3441 {
35- options . DefaultAuthenticateScheme = JwtBearerDefaults . AuthenticationScheme ;
36- options . DefaultAuthenticateScheme = JwtBearerDefaults . AuthenticationScheme ;
37- options . DefaultChallengeScheme = JwtBearerDefaults . AuthenticationScheme ;
38- } )
39- . AddJwtBearer ( options =>
42+ // Development environment code
43+ // Validation for bearer token for authorization used during testing.
44+ // This is not meant to replace proper OAuth for authentication purposes.
45+ services . AddAuthentication ( options =>
4046 {
41- options . TokenValidationParameters =
42- new TokenValidationParameters
47+ options . DefaultAuthenticateScheme = JwtBearerDefaults . AuthenticationScheme ;
48+ options . DefaultAuthenticateScheme = JwtBearerDefaults . AuthenticationScheme ;
49+ options . DefaultChallengeScheme = JwtBearerDefaults . AuthenticationScheme ;
50+ } )
51+ . AddJwtBearer ( options =>
52+ {
53+ options . TokenValidationParameters =
54+ new TokenValidationParameters
55+ {
56+ ValidateIssuer = false ,
57+ ValidateAudience = false ,
58+ ValidateLifetime = false ,
59+ ValidateIssuerSigningKey = false ,
60+ ValidIssuer = this . _configuration [ "Token:TokenIssuer" ] ,
61+ ValidAudience = this . _configuration [ "Token:TokenAudience" ] ,
62+ IssuerSigningKey = new SymmetricSecurityKey ( Encoding . UTF8 . GetBytes ( this . _configuration [ "Token:IssuerSigningKey" ] ) )
63+ } ;
64+ } ) ;
65+ }
66+ else
67+ {
68+ // Azure AD token validation code
69+ services . AddAuthentication ( options =>
70+ {
71+ options . DefaultAuthenticateScheme = JwtBearerDefaults . AuthenticationScheme ;
72+ options . DefaultAuthenticateScheme = JwtBearerDefaults . AuthenticationScheme ;
73+ options . DefaultChallengeScheme = JwtBearerDefaults . AuthenticationScheme ;
74+ } )
75+ . AddJwtBearer ( options =>
76+ {
77+ options . Authority = this . _configuration [ "Token:TokenIssuer" ] ;
78+ options . Audience = this . _configuration [ "Token:TokenAudience" ] ;
79+ options . Events = new JwtBearerEvents
4380 {
44- ValidateIssuer = false ,
45- ValidateAudience = false ,
46- ValidateLifetime = false ,
47- ValidateIssuerSigningKey = false ,
48- ValidIssuer = ServiceConstants . TokenIssuer ,
49- ValidAudience = ServiceConstants . TokenAudience ,
50- IssuerSigningKey = new SymmetricSecurityKey ( Encoding . UTF8 . GetBytes ( ServiceConstants . TokenIssuer ) )
81+ OnTokenValidated = context =>
82+ {
83+ // NOTE: You can optionally take action when the OAuth 2.0 bearer token was validated.
84+
85+ return Task . CompletedTask ;
86+ } ,
87+ OnAuthenticationFailed = AuthenticationFailed
5188 } ;
52- } ) ;
89+ } ) ;
90+ }
5391
5492 services . AddControllers ( ) . AddNewtonsoftJson ( ) ;
5593
@@ -58,9 +96,9 @@ public void ConfigureServices(IServiceCollection services)
5896 }
5997
6098 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
61- public void Configure ( IApplicationBuilder app , IWebHostEnvironment env )
99+ public void Configure ( IApplicationBuilder app )
62100 {
63- if ( env . IsDevelopment ( ) )
101+ if ( _env . IsDevelopment ( ) )
64102 {
65103 app . UseDeveloperExceptionPage ( ) ;
66104 }
@@ -78,5 +116,16 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
78116 endpoints . MapDefaultControllerRoute ( ) ;
79117 } ) ;
80118 }
119+
120+ private Task AuthenticationFailed ( AuthenticationFailedContext arg )
121+ {
122+ // For debugging purposes only!
123+ var s = $ "{{AuthenticationFailed: '{ arg . Exception . Message } '}}";
124+
125+ arg . Response . ContentLength = s . Length ;
126+ arg . Response . Body . WriteAsync ( Encoding . UTF8 . GetBytes ( s ) , 0 , s . Length ) ;
127+
128+ return Task . FromException ( arg . Exception ) ;
129+ }
81130 }
82131}
0 commit comments