插件:
Okta.AspNet;
Okta.AspNet.Abstractions
JWT;
Microsoft.Owin;
IdentityModel.Client;
配置:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new CookieAuthenticationOptions()
{
AuthenticationType = "AuthenticationType",
CookieName = "CookieName",
CookieSecure = CookieSecureOption.Always,
CookieHttpOnly = true,
CookieSameSite = SameSiteMode.Lax,
ReturnUrlParameter = "ReturnUrlParameter",
LoginPath = "/Account/Login",
LogoutPath = "/Account/Login",
SlidingExpiration = true,
ExpireTimeSpan = ExpireTimeSpan,
config.CookieDomain = CookieDomain
};
app.SetDefaultSignInAsAuthenticationType("AuthenticationType");
app.UseCookieAuthentication(config);
app.UseOktaMvc(new OktaMvcOptions
{
OktaDomain = "www.okta.com",
ClientId = "ClientId",
ClientSecret = "ClientSecret",
AuthorizationServerId = "AuthorizationServerId",
RedirectUri = "www.test.com",
PostLogoutRedirectUri = "www.test.com",
Scope= new List
OpenIdConnectEvents = new Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationNotifications()
{
AuthenticationFailed = AuthenticationFailed,
SecurityTokenValidated = SecurityTokenValidated,
AuthorizationCodeReceived = AuthorizationCodeReceived,
}
});
}
public Task SecurityTokenValidated(SecurityTokenValidatedNotification
{
if (context.AuthenticationTicket.Identity.IsAuthenticated)//执行这个事件,说明已登录成功了,加不加这个判断都一样
{
if (context.AuthenticationTicket.Identity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value != null)
{
var claimlist = context.AuthenticationTicket.Identity.Claims;
var claimsDic = new Dictionary
var s = string.Empty;
foreach (var item in claimlist)
{
if (!claimsDic.ContainsKey(item.Type))
{
claimsDic.Add(item.Type, item.Value);
}
}
var preferred_username = context.AuthenticationTicket.Identity.Claims.FirstOrDefault(c => c.Type == "preferred_username").Value;
//系统登录
}
}
return Task.FromResult(false);
}
public Task AuthenticationFailed(AuthenticationFailedNotification
{
t.Response.Redirect("/Home/Index");
t.HandleResponse();
return Task.FromResult(false);
}
public async Task AuthorizationCodeReceived(AuthorizationCodeReceivedNotification context)
{
var a = new TokenClient(new HttpMessageInvoker(new HttpClientHandler()), new TokenClientOptions()
{
ClientId = "ClientId",
ClientSecret = "ClientId",
Address = " ",
});
var rtoken = await a.RequestAuthorizationCodeTokenAsync(context.Code, "RedirectUri");
if (rtoken != null)
{
var id_token = rtoken.IdentityToken;
var access_token = rtoken.AccessToken;
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, urlEncoder);
var json = decoder.Decode(new JwtParts(id_token));
TokenObj tokenObj = Newtonsoft.Json.JsonConvert.DeserializeObject
var preferred_username = tokenObj.preferred_username;
}
}
}
登录/退出
public ActionResult Login()
{
if (!HttpContext.User.Identity.IsAuthenticated && !Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(
OktaDefaults.MvcAuthenticationType);
}
return RedirectToAction("Index", "Home");
}
public ActionResult Logout()
{
if (HttpContext.User.Identity.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.SignOut(
CookieAuthenticationDefaults.AuthenticationType,
OktaDefaults.MvcAuthenticationType);
return RedirectToAction("login", "Account");
}
return RedirectToAction("Index", "Home");
}
api接口调用:链接报404/403/401/402/400有可能是链接最后的"/"问题,可以尝试去掉"/",是因为c#将链接转uri对象的时候出现问题。
public async Task
{
var t = new RequestResultData()
{
IsSuccess = false,
RequestData = string.Empty,
ResponseData = string.Empty
};
string ClientId = httpSSORequestData.ClientId;
string ClientSecret = httpSSORequestData.ClientSecret;
var url = httpSSORequestData.url;
var json = JsonConvert.SerializeObject(model, Formatting.None, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver(),
});
t.RequestData = json;
var data = new StringContent(json, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
try
{
client.SetBasicAuthentication(ClientId, ClientSecret);
//string base64 = Convert.ToBase64String(Encoding.Default.GetBytes($"{ClientId}:{ClientSecret}"));
//client.DefaultRequestHeaders.Add($"Authorization", $"Basic " + base64);
t.RequestDateTime = DateTime.Now;
var response = await client.PostAsync(url, data);
t.ResponseDateTime = DateTime.Now;
var resp = await response.Content.ReadAsStringAsync();
t.ResponseData = resp;
var oktaUserRegResponse = JsonConvert.DeserializeObject
t.IsSuccess = oktaUserRegResponse != null && oktaUserRegResponse.status;
}
catch (Exception e)
{
}
}
return t;
}
帮助类:
public class RequestResultData
{
public bool IsSuccess { get; set; }
public string ResponseData { get; set; }
public string RequestData { get; set; }
public DateTime RequestDateTime { get; set; }
public DateTime ResponseDateTime { get; set; }
}
public class HttpSSORequestData
{
public string url { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
}
当从控制台中跳转到系统时会传递id_token过来,并且规定好的链接是home/index
所有在BeginExecuteCore中拦截,也可以在home/index
public void NotAuthentionUser() {
string id_token = Request["id_token"];
if (!string.IsNullOrEmpty(id_token) && (HttpContext.Request.Url.AbsolutePath == "/" || HttpContext.Request.Url.AbsolutePath == "/Home/Index"))
{
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, urlEncoder);
var json = decoder.Decode(new JwtParts(id_token));
TokenObj tokenObj = Newtonsoft.Json.JsonConvert.DeserializeObject
if (tokenObj != null && tokenObj.iss == ‘www.okta.com’)
{
//登录
HttpContext.Response.Redirect("/Home/index");
Response.End();
}
}
}