-
Notifications
You must be signed in to change notification settings - Fork 163
/
Startup.cs
132 lines (111 loc) · 5.35 KB
/
Startup.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
using IdentityModel;
using IdentityModel.AspNetCore;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace AspNetCoreSecurity
{
public class Startup
{
public Startup()
{
// lame
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
services.AddMvc(options =>
{
var global = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(global));
}).SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1);
services.AddAuthentication(options =>
{
options.DefaultScheme = "cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("cookies", options =>
{
options.AccessDeniedPath = "/account/denied";
})
.AddAutomaticTokenManagement()
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://demo.identityserver.io";
options.ClientId = "native.code";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.Scope.Add("offline_access");
options.Scope.Add("api");
options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce", "iat", "c_hash", "at_hash");
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
options.Events.OnRedirectToIdentityProvider = context =>
{
// only modify requests to the authorization endpoint
if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
{
// generate code_verifier
var codeVerifier = CryptoRandom.CreateUniqueId(32);
// store codeVerifier for later use
context.Properties.Items.Add(OidcConstants.TokenRequest.CodeVerifier, codeVerifier);
// create code_challenge
string codeChallenge;
using (var sha256 = SHA256.Create())
{
var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
codeChallenge = Base64Url.Encode(challengeBytes);
}
// add code_challenge and code_challenge_method to request
context.ProtocolMessage.Parameters.Add(OidcConstants.AuthorizeRequest.CodeChallenge, codeChallenge);
context.ProtocolMessage.Parameters.Add(OidcConstants.AuthorizeRequest.CodeChallengeMethod, OidcConstants.CodeChallengeMethods.Sha256);
}
return Task.CompletedTask;
};
options.Events.OnAuthorizationCodeReceived = context =>
{
// only when authorization code is being swapped for tokens
if (context.TokenEndpointRequest?.GrantType == OpenIdConnectGrantTypes.AuthorizationCode)
{
// get stored code_verifier
if (context.Properties.Items.TryGetValue(OidcConstants.TokenRequest.CodeVerifier, out var codeVerifier))
{
// add code_verifier to token request
context.TokenEndpointRequest.Parameters.Add(OidcConstants.TokenRequest.CodeVerifier, codeVerifier);
}
}
return Task.CompletedTask;
};
});
}
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
}
}