public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request) { // TODO: WARN: Property 'redirect' does not exist on type 'ServiceStack.Authenticate' // TODO: WARN: Property 'code' does not exist on type 'ServiceStack.Authenticate' // TODO: WARN: Property 'session_state' does not exist on type 'ServiceStack.Authenticate' // TODO: The base Init() should strip the query string from the request URL if (CallbackUrl.IsNullOrEmpty()) { CallbackUrl = new Uri(authService.Request.AbsoluteUri).GetLeftPart(UriPartial.Path); } var tokens = Init(authService, ref session, request); var httpRequest = authService.Request; var query = httpRequest.QueryString.ToNameValueCollection(); if (HasError(query)) { return(RedirectDueToFailure(authService, session, query)); } // 1. The client application starts the flow by redirecting the user agent // to the Azure AD authorization endpoint. The user authenticates and // consents, if consent is required. // TODO: Can State property be added to IAuthSession to avoid this cast var userSession = session as AuthUserSession; if (userSession == null) { throw new NotSupportedException("Concrete dependence on AuthUserSession because of State property"); } var code = query["code"]; if (code.IsNullOrEmpty()) { return(RequestCode(authService, session, userSession, tokens)); } var state = query["state"]; if (state != userSession.State) { session.IsAuthenticated = false; throw new UnauthorizedAccessException("Mismatched state in code response."); } // 2. The Azure AD authorization endpoint redirects the user agent back // to the client application with an authorization code. The user // agent returns authorization code to the client application’s redirect URI. // 3. The client application requests an access token from the // Azure AD token issuance endpoint. It presents the authorization code // to prove that the user has consented. return(RequestAccessToken(authService, session, code, tokens)); }
// Implementation taken from @jfoshee Servicestack.Authentication.Aad // https://github.com/jfoshee/ServiceStack.Authentication.Aad/blob/master/ServiceStack.Authentication.Aad/AadAuthProvider.cs public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request) { var uri = new Uri(authService.Request.AbsoluteUri); if (CallbackUrl.IsNullOrEmpty()) { CallbackUrl = $"{uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped)}/{uri.GetComponents(UriComponents.Path, UriFormat.SafeUnescaped)}"; } var tokens = Init(authService, ref session, request); var query = new NameValueCollection(); var httpRequest = authService.Request.QueryString; foreach (string s in httpRequest.AllKeys) { query.Add(s, httpRequest[s]); } // Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(authService.Request.AbsoluteUri) // .ForEach((key, values) => query.Add(key, values.ToString())); if (HasError(query)) { var result = RedirectDueToFailure(authService, session, query); return(result); } // TODO: Can State property be added to IAuthSession to avoid this cast var userSession = session as AuthUserSession; if (userSession == null) { throw new NotSupportedException("Concrete dependence on AuthUserSession because of State property"); } var code = query["code"]; if (code.IsNullOrEmpty()) { return(RequestCode(authService, request, session, userSession, tokens)); } var state = query["state"]; if (state != userSession.State) { session.IsAuthenticated = false; throw new UnauthorizedAccessException("Mismatched state in code response."); } return(RequestAccessToken(authService, session, code, tokens, request)); }
/// <summary>Initialise the Auth Token</summary> /// <param name="authService"></param> /// <param name="session"></param> /// <param name="request"></param> /// <returns></returns> protected new IAuthTokens Init(IServiceBase authService, ref IAuthSession session, Authenticate request) { if (CallbackUrl.IsNullOrEmpty()) { CallbackUrl = authService.Request.AbsoluteUri; } session.ReferrerUrl = GetReferrerUrl(authService, session, request); var tokens = session.ProviderOAuthAccess.FirstOrDefault(x => x.Provider == Provider); if (tokens == null) { session.ProviderOAuthAccess.Add(tokens = new IdentityServerAuthTokens { Provider = Provider }); } return(tokens); }
// Implementation taken from @jfoshee Servicestack.Authentication.Aad // https://github.com/jfoshee/ServiceStack.Authentication.Aad/blob/master/ServiceStack.Authentication.Aad/AadAuthProvider.cs public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request) { // TODO: WARN: Property 'redirect' does not exist on type 'ServiceStack.Authenticate' // TODO: WARN: Property 'code' does not exist on type 'ServiceStack.Authenticate' // TODO: WARN: Property 'session_state' does not exist on type 'ServiceStack.Authenticate' // TODO: The base Init() should strip the query string from the request URL if (CallbackUrl.IsNullOrEmpty()) { var uri = new Uri(authService.Request.AbsoluteUri); CallbackUrl = $"{uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped)}/{uri.GetComponents(UriComponents.Path, UriFormat.SafeUnescaped)}"; } var tokens = Init(authService, ref session, request); var httpRequest = authService.Request; var query = httpRequest.QueryString.ToNameValueCollection(); if (HasError(query)) { var result = RedirectDueToFailure(authService, session, query); return(result); } // TODO: Can State property be added to IAuthSession to avoid this cast var userSession = session as AuthUserSession; if (userSession == null) { throw new NotSupportedException("Concrete dependence on AuthUserSession because of State property"); } if (string.Compare(query["request_consent"], "true", StringComparison.OrdinalIgnoreCase) == 0) { var registration = CustomConsentRequestedHandler != null?CustomConsentRequestedHandler(authService, request, session) : GetDefaultConsentingDirectory(authService, request); if (registration.ConstentDateUtc == null) { return(RequestCode(authService, request, session, userSession, tokens, registration, true)); } } if (string.Compare(query["admin_consent"], "true", StringComparison.OrdinalIgnoreCase) == 0 && query["state"] == userSession.State) { OnConsentGranted?.Invoke(authService, userSession); GrantDirectoryConsent(authService, userSession); } var code = query["code"]; if (code.IsNullOrEmpty()) { var isValidAuthRequest = OnAuthenticationRequested?.Invoke(authService, session, request, query); if (OnAuthenticationRequested != null && isValidAuthRequest == false) { var result = RedirectDueToFailure(authService, session, query); return(result); } // TODO: ONLY ALLOW AUTHENTICATION TO CONSENTED DIRECTORIES return(RequestCode(authService, request, session, userSession, tokens)); } var state = query["state"]; if (state != userSession.State) { session.IsAuthenticated = false; throw new UnauthorizedAccessException("Mismatched state in code response."); } return(RequestAccessToken(authService, session, code, tokens)); }
public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request) { // TODO: WARN: Property 'redirect' does not exist on type 'ServiceStack.Authenticate' // TODO: WARN: Property 'code' does not exist on type 'ServiceStack.Authenticate' // TODO: WARN: Property 'session_state' does not exist on type 'ServiceStack.Authenticate' // TODO: The base Init() should strip the query string from the request URL if (CallbackUrl.IsNullOrEmpty()) { CallbackUrl = new Uri(authService.Request.AbsoluteUri).GetLeftPart(UriPartial.Path); } var tokens = Init(authService, ref session, request); var httpRequest = authService.Request; var query = httpRequest.QueryString; if (HasError(query.ToNameValueCollection())) { return(RedirectDueToFailure(authService, session, query.ToNameValueCollection())); } // 1. The client application starts the flow by redirecting the user agent // to the Azure AD authorization endpoint. The user authenticates and // consents, if consent is required. // TODO: Can State property be added to IAuthSession to avoid this cast var userSession = session as AuthUserSession; if (userSession == null) { throw new NotSupportedException("Concrete dependence on AuthUserSession because of State property"); } //var code = query["code"]; //if (code.IsNullOrEmpty()) // return RequestCode(authService, session, userSession, tokens); string code = httpRequest.FormData["access_token"]; if (code.IsNullOrEmpty()) { return(RequestCode(authService, session, userSession, tokens)); } var state = httpRequest.FormData["state"]; if (state != userSession.State) { session.IsAuthenticated = false; throw new UnauthorizedAccessException("Mismatched state in code response."); } // 2. The Azure AD authorization endpoint redirects the user agent back // to the client application with an authorization code. The user // agent returns authorization code to the client application’s redirect URI. // 3. The client application requests an access token from the // Azure AD token issuance endpoint. It presents the authorization code // to prove that the user has consented. // return RequestAccessToken(authService, session, code, tokens); // var authInfo = JsonObject.Parse(responseJson); // var authInfoNvc = authInfo.ToNameValueCollection(); //if (HasError(authInfoNvc)) // return RedirectDueToFailure(authService, session, authInfoNvc); tokens.AccessTokenSecret = code; // tokens.RefreshToken = authInfo["refresh_token"]; tokens.AccessToken = code; session.ReferrerUrl = AppSettings.Get <string>($"oauth.{Provider}.RedirectUrl", session.ReferrerUrl);; return(OnAuthenticated(authService, session, tokens, httpRequest.FormData.ToDictionary()) ?? authService.Redirect(SuccessRedirectUrlFilter(this, session.ReferrerUrl.SetParam("s", "1")))); //Haz Access! }