public OAuth2Controller(UserManager <ApplicationUser> userManager, ApplicationDbContext dbContext, IOptions <OAuth2Configuration> oauth2Configuration) { _userManager = userManager; _dbContext = dbContext; _oauth2Configuration = oauth2Configuration.Value; _oauth2Clients = _oauth2Configuration.Clients.ToDictionary(c => c.ClientId); }
/// <summary> /// Adds the default Authorization HTTP header as appropriate for the OAuth configuration. /// </summary> /// <param name="pluginConfiguration">The configuration for the OAuth 2.0 plugin.</param> /// <param name="oAuthTokens">The access tokens retrieved via the OAuth flow.</param> /// <param name="clearAuthenticationToken">If true, calls <see cref="ClearAuthenticationToken"/> first.</param> /// <remarks><see cref="OAuth2Configuration.UseIdTokenAsAccessToken"/> defines whether <see cref="OAuth2TokenResponse.IdToken"/> (if true) or /// <see cref="OAuth2TokenResponse.AccessToken"/> (if false) should be used for the bearer value.</remarks> public void AddAuthorizationHeader ( OAuth2Configuration pluginConfiguration, OAuth2TokenResponse oAuthTokens, bool clearAuthenticationToken = true ) { // Sanity. if (null == pluginConfiguration) { throw new ArgumentNullException(nameof(pluginConfiguration)); } // Clear the authorisation token. if (clearAuthenticationToken) { this.ClearAuthenticationToken(); } // Add the authorisation token to the headers. if (pluginConfiguration.UseIdTokenAsAccessToken) { this.AddDefaultHeader(MFWSClient.AuthorizationHttpHeaderName, "Bearer " + oAuthTokens.IdToken); } else { this.AddDefaultHeader(MFWSClient.AuthorizationHttpHeaderName, "Bearer " + oAuthTokens.AccessToken); } }
/// <summary> /// Handles the redirection from the AuthorizationEndpoint when using OAuth 2.0 authentication. /// Automatically calls <see cref="ConvertOAuth2AuthorizationCodeToTokens"/> and <see cref="AddAuthorizationHeader"/> /// as appropriate. /// </summary> /// <param name="configuration">The OAuth 2.0 configuration.</param> /// <param name="redirectionUri">The URI that was redirected to.</param> /// <param name="setHttpHeaders">If true, <see cref="AddAuthorizationHeader"/> will be called automatically.</param> /// <param name="token">A cancellation token for the task.</param> /// <remarks>Callees must ensure that this method is only called for the valid redirect Uri.</remarks> public async Task <OAuth2TokenResponse> GenerateTokensFromOAuthRedirectAsync( OAuth2Configuration configuration, Uri redirectionUri, bool setHttpHeaders = true, CancellationToken token = default(CancellationToken)) { // Sanity. if (null == configuration) { throw new ArgumentNullException(nameof(configuration)); } if (null == redirectionUri) { throw new ArgumentNullException(nameof(redirectionUri)); } // Parse the querystring into a dictionary so we can get the data easily. var uriQueryParams = (new UriBuilder(redirectionUri)) .GetQueryParamsDictionary(); // Was it an error? // e.g. http://localhost?error=errorcode&error_description=some+text if (uriQueryParams.ContainsKey("error")) { var errorDetails = uriQueryParams.GetValueOrDefault("error_description", "no details provided"); throw new ArgumentException( $"Exception {uriQueryParams["error"]} returned by authorization endpoint: {errorDetails}", nameof(redirectionUri)); } // If we have a state in the OAuth configuration then it must match the state being returned. if (false == string.IsNullOrWhiteSpace(configuration.State) && (false == uriQueryParams.ContainsKey("state") || uriQueryParams["state"] != configuration.State) ) { throw new InvalidOperationException("The state returned by the AuthorizationEndpoint was not correct."); } // Grab the authentication code, which we'll use to get OAuth tokens. var code = uriQueryParams .ContainsKey("code") ? uriQueryParams["code"] : null; // Convert the code to a set of OAuth tokens. var tokens = await this.ConvertOAuth2AuthorizationCodeToTokensAsync(configuration, code, token); // Set the authorisation header. if (setHttpHeaders) { if (Guid.TryParse(configuration.VaultGuid, out Guid vaultGuid)) { this.AddDefaultHeader("X-Vault", vaultGuid.ToString("B")); } this.AddAuthorizationHeader(configuration, tokens, clearAuthenticationToken: false); } // Return the tokens. return(tokens); }
/// <summary> /// Refreshes the OAuth 2.0 access token using the refresh token provided. /// </summary> /// <param name="pluginConfiguration">The configuration for the OAuth 2.0 identity provider.</param> /// <param name="refreshToken">The refresh token.</param> /// <param name="setHttpHeaders">If true, <see cref="AddAuthorizationHeader"/> will be called automatically.</param> /// <param name="token">A cancellation token for the task.</param> /// <returns>The updated access token data.</returns> public async Task <OAuth2TokenResponse> RefreshOAuth2TokenAsync( OAuth2Configuration pluginConfiguration, string refreshToken, bool setHttpHeaders = true, CancellationToken token = default(CancellationToken)) { // Sanity. if (null == pluginConfiguration) { throw new ArgumentNullException(nameof(pluginConfiguration)); } if (string.IsNullOrWhiteSpace(refreshToken)) { throw new ArgumentException("The OAuth 2.0 refresh token cannot be empty.", nameof(refreshToken)); } // Create the request, adding the mandatory items. var tokenEndpoint = new Uri(pluginConfiguration.TokenEndpoint, uriKind: UriKind.Absolute); var request = new RestSharp.RestRequest(tokenEndpoint.PathAndQuery, RestSharp.Method.POST); request.AddParameter("grant_type", "refresh_token"); request.AddParameter("refresh_token", refreshToken); request.AddParameter("redirect_uri", pluginConfiguration.GetAppropriateRedirectUri()); // Add the client id. If there's a realm then use that here too. request.AddParameter( "client_id", string.IsNullOrWhiteSpace(pluginConfiguration.SiteRealm) ? pluginConfiguration.ClientID // If no site realm is supplied, just pass the client ID. : $"{pluginConfiguration.ClientID}@{pluginConfiguration.SiteRealm}" // Otherwise pass client ID @ site realm. ); // Add the optional bits. request.AddParameterIfNotNullOrWhitespace("resource", pluginConfiguration.Resource); request.AddParameterIfNotNullOrWhitespace("scope", pluginConfiguration.Scope); request.AddParameterIfNotNullOrWhitespace("client_secret", pluginConfiguration.ClientSecret); // Make a post to the token endpoint. // NOTE: We must use a new RestClient here otherwise it'll try and add the token endpoint to the MFWA base url. var restClient = new RestSharp.RestClient(tokenEndpoint.GetLeftPart(UriPartial.Authority)); var response = await restClient.ExecutePostAsync <OAuth2TokenResponse>(request, token); // Validate response. if (null == response.Data || response.Data.TokenType != "Bearer") { throw new InvalidOperationException("OAuth token not received from endpoint, or token type was not bearer."); } // Set the authorisation header. if (setHttpHeaders) { this.AddAuthorizationHeader(pluginConfiguration, response.Data); } // Return the access token data. return(response.Data); }
public EmbeddedHtmlResult(HttpRequestMessage request, string file, OAuth2Configuration oauthConfig = null) { this.path = request.GetOwinContext().Request.PathBase.Value; this.file = file; this.oauthConfig = oauthConfig; if (oauthConfig != null && oauthConfig.AutomaticallyRenewToken) { this.frameCallbackUrl = request.GetUrlHelper().Link(Constants.RouteNames.OAuthFrameCallback, null); } }
/// <summary> /// Using the <see paramref="code"/> from the OAuth authorisation endpoint, /// requests tokens from the token endpoint and sets up the client to use them. /// The token data is returned in case it is needed in the future (e.g. <see cref="RefreshOAuth2TokenAsync(MFaaP.MFWSClient.OAuth2.OAuth2Configuration,MFaaP.MFWSClient.OAuth2.OAuth2TokenResponse,bool,System.Threading.CancellationToken)"/>). /// </summary> /// <param name="pluginConfiguration">The configuration of the OAuth plugin.</param> /// <param name="code">The code returned from the OAuth authorisation endpoint.</param> /// <param name="cancellationToken">A cancellation token for the task.</param> /// <returns>The data returned from the token endpoint.</returns> protected async Task <OAuth2TokenResponse> ConvertOAuth2AuthorizationCodeToTokensAsync( OAuth2Configuration pluginConfiguration, string code, CancellationToken cancellationToken = default(CancellationToken)) { // Sanity. if (null == pluginConfiguration) { throw new ArgumentNullException(nameof(pluginConfiguration)); } if (null == code) { throw new ArgumentNullException(nameof(code)); } // Create the request, adding the mandatory items. var tokenEndpoint = new Uri(pluginConfiguration.TokenEndpoint, uriKind: UriKind.Absolute); var request = new RestSharp.RestRequest(tokenEndpoint.PathAndQuery, RestSharp.Method.POST); request.AddParameter("code", code); request.AddParameter("grant_type", pluginConfiguration.GrantType); request.AddParameter("redirect_uri", pluginConfiguration.GetAppropriateRedirectUri()); // Add the client id. If there's a realm then use that here too. request.AddParameter( "client_id", string.IsNullOrWhiteSpace(pluginConfiguration.SiteRealm) ? pluginConfiguration.ClientID // If no site realm is supplied, just pass the client ID. : $"{pluginConfiguration.ClientID}@{pluginConfiguration.SiteRealm}" // Otherwise pass client ID @ site realm. ); // Add the optional bits. request.AddParameterIfNotNullOrWhitespace("resource", pluginConfiguration.Resource); request.AddParameterIfNotNullOrWhitespace("scope", pluginConfiguration.Scope); request.AddParameterIfNotNullOrWhitespace("client_secret", pluginConfiguration.ClientSecret); // Make a post to the token endpoint. // NOTE: We must use a new RestClient here otherwise it'll try and add the token endpoint to the MFWA base url. var restClient = new RestSharp.RestClient(tokenEndpoint.GetLeftPart(UriPartial.Authority)); var response = await restClient.ExecutePostTaskAsync <OAuth2TokenResponse>(request, cancellationToken); // Validate response. if (null == response.Data) { throw new InvalidOperationException("OAuth token not received from endpoint. Response: " + response.Content); } else if (response.Data.TokenType != "Bearer") { throw new InvalidOperationException("Token type was not bearer. Response: " + response.Content); } // Return the access token data. return(response.Data); }
/// <summary> /// Obtains the plugin configuration for the OAuth 2.0 authentication process. /// </summary> /// <param name="pluginInfoConfiguration">The list of defined authentication plugins defined.</param> /// <param name="oAuth2Configuration">The configuration, if found, or null otherwise.</param> /// <returns>True if OAuth is found, false otherwise.</returns> public static bool TryGetOAuth2Configuration(this IEnumerable <PluginInfoConfiguration> pluginInfoConfiguration, out OAuth2Configuration oAuth2Configuration) { // Is OAuth 2.0 specified? oAuth2Configuration = pluginInfoConfiguration? .Where(pic => pic.Protocol == IEnumerablePluginInfoConfigurationExtensionMethods.OAuth2PluginConfigurationProtocol)? .Select(pic => OAuth2Configuration.ParseFrom(pic.Configuration, pic.VaultGuid))? .FirstOrDefault(); // Did we get a value? return(oAuth2Configuration != null); }
/// <summary> /// Refreshes the OAuth 2.0 access token using the refresh token provided. /// </summary> /// <param name="pluginConfiguration">The configuration for the OAuth 2.0 identity provider.</param> /// <param name="refreshToken">The refresh token.</param> /// <param name="setHttpHeaders">If true, <see cref="AddAuthorizationHeader"/> will be called automatically.</param> /// <param name="token">A cancellation token for the task.</param> /// <returns>The updated access token data.</returns> public OAuth2TokenResponse RefreshOAuth2Token( OAuth2Configuration pluginConfiguration, string refreshToken, bool setHttpHeaders = true, CancellationToken token = default(CancellationToken)) { // Execute the async method. return(this.RefreshOAuth2TokenAsync(pluginConfiguration, refreshToken, setHttpHeaders, token) .ConfigureAwait(false) .GetAwaiter() .GetResult()); }
/// <summary> /// Obtains the plugin configuration for the OAuth 2.0 authentication process. /// </summary> /// <param name="pluginInfoConfiguration">The list of defined authentication plugins defined.</param> /// <param name="oAuth2Configuration">The configuration, if found, or null otherwise.</param> /// <returns>True if OAuth is found, false otherwise.</returns> public static bool TryGetOAuth2Configuration(this IEnumerable <PluginInfoConfiguration> pluginInfoConfiguration, out OAuth2Configuration oAuth2Configuration) { // Sanity. if (null == pluginInfoConfiguration) { throw new ArgumentNullException(nameof(pluginInfoConfiguration)); } // Is OAuth 2.0 specified? oAuth2Configuration = pluginInfoConfiguration .Where(pic => pic.Protocol == IEnumerablePluginInfoConfigurationExtensionMethods.OAuth2PluginConfigurationProtocol) .Select(pic => OAuth2Configuration.ParseFrom(pic.Configuration)) .FirstOrDefault(); // Did we get a value? return(oAuth2Configuration != null); }
/// <summary> /// Refreshes the OAuth 2.0 access token using the refresh token provided. /// </summary> /// <param name="pluginConfiguration">The configuration for the OAuth 2.0 identity provider.</param> /// <param name="oAuthTokens">The OAuth 2.0 tokens.</param> /// <param name="setHttpHeaders">If true, <see cref="AddAuthorizationHeader"/> will be called automatically.</param> /// <param name="token">A cancellation token for the task.</param> /// <returns>The updated access token data.</returns> public Task <OAuth2TokenResponse> RefreshOAuth2TokenAsync( OAuth2Configuration pluginConfiguration, OAuth2TokenResponse oAuthTokens, bool setHttpHeaders = true, CancellationToken token = default(CancellationToken)) { // Sanity. if (null == pluginConfiguration) { throw new ArgumentNullException(nameof(pluginConfiguration)); } if (null == oAuthTokens) { throw new ArgumentNullException(nameof(oAuthTokens)); } // Execute the other overload. return(this.RefreshOAuth2TokenAsync(pluginConfiguration, oAuthTokens.RefreshToken, setHttpHeaders, token)); }
/// <summary> /// Using the <see paramref="code"/> from the OAuth authorisation endpoint, /// requests tokens from the token endpoint and sets up the client to use them. /// The token data is returned in case it is needed in the future (e.g. /// <see cref="RefreshOAuth2TokenAsync(OAuth2Configuration, OAuth2TokenResponse, bool, CancellationToken)"/>). /// </summary> /// <param name="pluginConfiguration">The configuration of the OAuth plugin.</param> /// <param name="code">The code returned from the OAuth authorisation endpoint.</param> /// <param name="cancellationToken">A cancellation token for the task.</param> /// <returns>The data returned from the token endpoint.</returns> protected OAuth2TokenResponse ConvertOAuth2AuthorizationCodeToTokens( OAuth2Configuration pluginConfiguration, string code, CancellationToken cancellationToken = default(CancellationToken)) { // Sanity. if (null == pluginConfiguration) { throw new ArgumentNullException(nameof(pluginConfiguration)); } if (null == code) { throw new ArgumentNullException(nameof(code)); } // Execute the async method. return(this.ConvertOAuth2AuthorizationCodeToTokensAsync(pluginConfiguration, code, cancellationToken) .ConfigureAwait(false) .GetAwaiter() .GetResult()); }
/// <summary> /// Handles the redirection from the AuthorizationEndpoint when using OAuth 2.0 authentication. /// </summary> /// <param name="configuration">The OAuth 2.0 configuration.</param> /// <param name="redirectionUri">The URI that was redirected to.</param> /// <param name="setHttpHeaders">If true, <see cref="AddAuthorizationHeader"/> will be called automatically.</param> /// <param name="token">A cancellation token for the task.</param> /// <remarks>Callees must ensure that this method is only called for the valid redirect Uri.</remarks> public OAuth2TokenResponse HandleOAuth2AuthorizationEndpointRedirectData( OAuth2Configuration configuration, Uri redirectionUri, bool setHttpHeaders = true, CancellationToken token = default(CancellationToken)) { // Sanity. if (null == configuration) { throw new ArgumentNullException(nameof(configuration)); } if (null == redirectionUri) { throw new ArgumentNullException(nameof(redirectionUri)); } // Execute the async method. return(this.HandleOAuth2AuthorizationEndpointRedirectDataAsync(configuration, redirectionUri, setHttpHeaders, token) .ConfigureAwait(false) .GetAwaiter() .GetResult()); }
public GoogleLogin(ILogger <GoogleLogin> logger, OAuth2Configuration <GoogleLogin> configuration) : base(logger, configuration) { }
public void Configure() { BlogDB.Reset(); using (OpenRastaConfiguration.Manual) { ResourceSpace.Has.ResourcesOfType <SyndicationFeed>() .AtUri(Constants.AtomFeedPath) .HandledBy <FeedHandler>() .TranscodedBy <AtomFeedCodec>(); ResourceSpace.Has.ResourcesOfType <SyndicationItem>() .AtUri(Constants.AtomItemPath) .HandledBy <FeedHandler>() .TranscodedBy <AtomItemCodec>(); ResourceSpace.Has.ResourcesOfType <string>() .AtUri("/texts/plain") .HandledBy <TextHandler>() .TranscodedBy <TextCodec>() .ForMediaType("text/plain"); ResourceSpace.Has.ResourcesOfType <Cat>() .AtUri(Constants.CatPath) .And.AtUri(Constants.CatsPath) .HandledBy <CatHandler>() .TranscodedBy <CatAsTextCodec>() .And.TranscodedBy <CatAsHtmlCodec>() .And.TranscodedBy <CatAsXmlCodec>() .And.TranscodedBy <CatAsJsonCodec>() .And.TranscodedBy <CatsAsJsonCodec>(); ResourceSpace.Has.ResourcesOfType <Dog2>() .AtUri(Constants.DogPath) .HandledBy <DogHandler>() .TranscodedBy <Dog2AsXmlCodec>(); ResourceSpace.Has.ResourcesOfType <Person>() .AtUri(Constants.PersonPath) .HandledBy <PersonHandler>() .RenderedByAspx("~/Views/Person.aspx"); ResourceSpace.Has.ResourcesOfType <EncodingData>() .AtUri(Constants.EncodingPath) .HandledBy <EncodingHandler>() .TranscodedBy <EncodingCodec>(); ResourceSpace.Has.ResourcesOfType <MyFileResource>() .AtUri(Constants.FilePath) .HandledBy <FileHandler>() .TranscodedBy <ApplicationOctetStreamCodec>(); ResourceSpace.Has.ResourcesOfType <MultipartData>() .AtUri(Constants.MultipartFormDataPath).Named("SimpleData") .And.AtUri(Constants.MultipartFormDataFilePath).Named("FileData") .HandledBy <MultipartFormDataHandler>() .TranscodedBy <EncodingCodec>(); ResourceSpace.Has.ResourcesOfType <FormUrlEncodedData>() .AtUri(Constants.FormUrlEncodedPath) .HandledBy <FormUrlEncodedHandler>() .TranscodedBy <FormUrlencodedCodec>(); ResourceSpace.Has.ResourcesOfType <HeaderList>() .AtUri(Constants.HeaderEchoPath) .HandledBy <HeaderEchoHandler>() .TranscodedBy <HeaderEchoCodec>(); ResourceSpace.Has.ResourcesOfType <XmlEcho>() .AtUri(Constants.XmlEchoPath) .HandledBy <XmlEchoHandler>() .TranscodedBy <XmlEchoCodec>(); ResourceSpace.Has.ResourcesOfType <AnyEcho>() .AtUri(Constants.AnyEchoPath) .HandledBy <AnyEchoHandler>() .TranscodedBy <AnyEchoCodec>(); ResourceSpace.Has.ResourcesOfType <ComplexClassForOpenRastaSerializationTests>() .AtUri(Constants.ComplexClassPath) .HandledBy <ComplexClassHandler>() .TranscodedBy <TextCodec>() .ForMediaType("application/x-www-form-urlencoded"); ResourceSpace.Has.ResourcesOfType <TestForm>() .AtUri(Constants.FormPath) .And.AtUri(Constants.FormSimplePath) .HandledBy <FormHandler>() .RenderedByAspx("~/Views/Form.aspx") .And.TranscodedBy <FormUrlencodedCodec>(); ResourceSpace.Has.ResourcesOfType <FileDownload>() .AtUri(Constants.FileDownloadPath) .HandledBy <FileDownloadHandler>() .TranscodedBy <FileDownloadCodec>(); ResourceSpace.Has.ResourcesOfType <LinkHeader>() .AtUri(Constants.LinkHeaderPath) .HandledBy <LinkHeaderHandler>() .TranscodedBy <LinkHeaderCodec>(); ResourceSpace.Has.ResourcesOfType <JsonPatchDocument>() .AtUri(Constants.PatchPath) .HandledBy <PatchHandler>() .TranscodedBy <Ramone.Tests.Server.Codecs.JsonPatchDocumentCodec>(); ResourceSpace.Has.ResourcesOfType <SlowResource>() .AtUri(Constants.SlowPath) .HandledBy <SlowHandler>() .TranscodedBy <JsonSerializerCodec <SlowResource> >(); CMSConfiguration.Configure(); ResourceSpace.Has.ResourcesOfType <RedirectArgs>() .AtUri(Constants.RedirectPath) .HandledBy <RedirectHandler>() .TranscodedBy <FormUrlencodedCodec>(); ResourceSpace.Has.ResourcesOfType <HtmlPageResource>() .AtUri(Constants.HtmlPath) .HandledBy <HtmlHandler>() .RenderedByAspx("~/Views/Html.aspx"); ResourceSpace.Has.ResourcesOfType <ApplicationError>() .AtUri(Constants.ApplicationErrorPath) .HandledBy <ApplicationErrorHandler>() .TranscodedBy <JsonSerializerCodec <ApplicationError> >(); BlogConfiguration.Configure(); OAuth2Configuration.Configure(); } }
public EmbeddedHtmlResult(HttpRequestMessage request, string file, OAuth2Configuration oauthConfig = null) { this.path = request.GetOwinContext().Request.PathBase.Value; this.file = file; this.oauthConfig = oauthConfig; }
public OpenIdLogin(ILogger <OpenIdLogin> logger, OAuth2Configuration <OpenIdLogin> configuration, IUsernameFormatter usernameFormatter = null) : base(logger, configuration, usernameFormatter) { }