public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            ApplicationUser user;
            var             allowedOrigin = context.OwinContext.Get <string>("as:clientAllowedOrigin");

            if (allowedOrigin == null)
            {
                allowedOrigin = "*";
            }

            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });

            if (context.UserName.IndexOf("@petronas.com") >= 0)
            {
                var       request   = new LoginRequest();
                SSOHelper sSOHelper = new SSOHelper();
                var       ssoToken  = sSOHelper.Login(context.UserName, context.Password, "Petronas");
                if (ssoToken == null || ssoToken.Result == Guid.Empty)
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect.");
                    return;
                }
                user = await _repo.FindUser(context.UserName);
            }
            else
            //using (AuthRepository _repo = new AuthRepository())
            {
                user = await _repo.FindUser(context.UserName, context.Password);

                if (user == null)
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect.");
                    return;
                }
            }
            var roles    = _repo.GetUserRole(user.Id.ToString());
            var identity = new ClaimsIdentity(context.Options.AuthenticationType);

            identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            identity.AddClaim(new Claim(ClaimTypes.Role, Newtonsoft.Json.JsonConvert.SerializeObject(roles)));
            identity.AddClaim(new Claim("sub", context.UserName));

            var props = new AuthenticationProperties(new Dictionary <string, string>
            {
                {
                    "as:client_id", (context.ClientId == null) ? string.Empty : context.ClientId
                },
                {
                    "userName", context.UserName
                },
                {
                    "fullname", user.FirstName + " " + user.LastName
                },
                {
                    "roles", Newtonsoft.Json.JsonConvert.SerializeObject(roles)
                }
            });

            var ticket = new AuthenticationTicket(identity, props);

            context.Validated(ticket);
        }
        protected override async Task <AuthenticationTicket> CreateTicketAsync(
            [NotNull] ClaimsIdentity identity, [NotNull] AuthenticationProperties properties,
            [NotNull] string identifier, [NotNull] IDictionary <string, string> attributes)
        {
            var principal = new ClaimsPrincipal(identity);
            var ticket    = new AuthenticationTicket(principal, properties, Scheme.Name);

            // Return the authentication ticket as-is if the
            // user information endpoint has not been set.
            if (string.IsNullOrEmpty(Options.UserInformationEndpoint))
            {
                Logger.LogInformation("The userinfo request was skipped because no userinfo endpoint was configured.");

                return(ticket);
            }

            // Return the authentication ticket as-is
            // if the application key has not been set.
            if (string.IsNullOrEmpty(Options.ApplicationKey))
            {
                Logger.LogInformation("The userinfo request was skipped because no application key was configured.");

                return(ticket);
            }

            // Return the authentication ticket as-is if the claimed identifier is malformed.
            if (!identifier.StartsWith(SteamAuthenticationConstants.Namespaces.Identifier, StringComparison.Ordinal))
            {
                Logger.LogWarning("The userinfo request was skipped because an invalid identifier was received: {Identifier}.", identifier);

                return(ticket);
            }

            var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary <string, string>
            {
                [SteamAuthenticationConstants.Parameters.Key]     = Options.ApplicationKey,
                [SteamAuthenticationConstants.Parameters.SteamId] = identifier.Substring(SteamAuthenticationConstants.Namespaces.Identifier.Length)
            });

            var request = new HttpRequestMessage(HttpMethod.Get, address);

            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(OpenIdAuthenticationConstants.Media.Json));

            // Return the authentication ticket as-is if the userinfo request failed.
            var response = await Options.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogWarning("The userinfo request failed because an invalid response was received: the identity provider " +
                                  "returned returned a {Status} response with the following payload: {Headers} {Body}.",
                                  /* Status: */ response.StatusCode,
                                  /* Headers: */ response.Headers.ToString(),
                                  /* Body: */ await response.Content.ReadAsStringAsync());

                return(ticket);
            }

            var payload = JObject.Parse(await response.Content.ReadAsStringAsync());

            // Try to extract the profile name of the authenticated user.
            var profile = payload.Value <JObject>(SteamAuthenticationConstants.Parameters.Response)
                          ?.Value <JArray>(SteamAuthenticationConstants.Parameters.Players)
                            ?[0]?.Value <string>(SteamAuthenticationConstants.Parameters.Name);

            if (!string.IsNullOrEmpty(profile))
            {
                identity.AddClaim(new Claim(ClaimTypes.Name, profile, ClaimValueTypes.String, Options.ClaimsIssuer));
            }

            var context = new OpenIdAuthenticatedContext(Context, Scheme, Options, ticket)
            {
                User = payload
            };

            // Copy the attributes to the context object.
            foreach (var attribute in attributes)
            {
                context.Attributes.Add(attribute);
            }

            await Events.Authenticated(context);

            // Note: return the authentication ticket associated
            // with the notification to allow replacing the ticket.
            return(context.Ticket);
        }
        /// <summary>
        /// TODO: must be generated by AIP and returned on the first request from MyX
        /// Then ticket will be used for Resources authorization
        /// </summary>
        /// <param name="request"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        private async Task <AuthenticationTicket> CreateTicketAsync(OpenIdConnectRequest request, AppUser user)
        {
            // Create a new ClaimsPrincipal containing the claims that
            // will be used to create an id_token, a token or a code.
            var principal = await _signInManager.CreateUserPrincipalAsync(user);

            // Create a new authentication ticket holding the user identity.
            var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), OpenIddictServerDefaults.AuthenticationScheme);

            //if (!request.IsRefreshTokenGrantType())
            //{
            // Set the list of scopes granted to the client application.
            // Note: the offline_access scope must be granted
            // to allow OpenIddict to return a refresh token.
            ticket.SetScopes(new[]
            {
                OpenIdConnectConstants.Scopes.OpenId,
                OpenIdConnectConstants.Scopes.Email,
                OpenIdConnectConstants.Scopes.Phone,
                OpenIdConnectConstants.Scopes.Profile,
                OpenIdConnectConstants.Scopes.OfflineAccess,
                OpenIddictConstants.Scopes.Roles
            }.Intersect(request.GetScopes()));
            //}

            //ticket.SetResources("webapp-api");

            // Note: by default, claims are NOT automatically included in the access and identity tokens.
            // To allow OpenIddict to serialize them, you must attach them a destination, that specifies
            // whether they should be included in access tokens, in identity tokens or in both.

            foreach (var claim in ticket.Principal.Claims)
            {
                // Never include the security stamp in the access and identity tokens, as it's a secret value.
                if (claim.Type == _identityOptions.Value.ClaimsIdentity.SecurityStampClaimType)
                {
                    continue;
                }

                var destinations = new List <string> {
                    OpenIdConnectConstants.Destinations.AccessToken
                };

                // Only add the iterated claim to the id_token if the corresponding scope was granted to the client application.
                // The other claims will only be added to the access_token, which is encrypted when using the default format.
                if ((claim.Type == OpenIdConnectConstants.Claims.Subject && ticket.HasScope(OpenIdConnectConstants.Scopes.OpenId)) ||
                    (claim.Type == OpenIdConnectConstants.Claims.Name && ticket.HasScope(OpenIdConnectConstants.Scopes.Profile)) ||
                    (claim.Type == OpenIdConnectConstants.Claims.Role && ticket.HasScope(OpenIddictConstants.Claims.Roles)) ||
                    (claim.Type == CustomClaimTypes.Permission && ticket.HasScope(OpenIddictConstants.Claims.Roles)))
                {
                    destinations.Add(OpenIdConnectConstants.Destinations.IdentityToken);
                }
                claim.SetDestinations(destinations);
            }

            var identity = principal.Identity as ClaimsIdentity;

            if (ticket.HasScope(OpenIdConnectConstants.Scopes.Profile))
            {
                if (!string.IsNullOrWhiteSpace(user.JobTitle))
                {
                    identity.AddClaim(CustomClaimTypes.JobTitle, user.JobTitle, OpenIdConnectConstants.Destinations.IdentityToken);
                }

                //if (!string.IsNullOrWhiteSpace(user.FullName))
                //    identity.AddClaim(CustomClaimTypes.FullName, user.FullName, OpenIdConnectConstants.Destinations.IdentityToken);

                if (!string.IsNullOrWhiteSpace(user.Configuration))
                {
                    identity.AddClaim(CustomClaimTypes.Configuration, user.Configuration, OpenIdConnectConstants.Destinations.IdentityToken);
                }
            }

            if (ticket.HasScope(OpenIdConnectConstants.Scopes.Email))
            {
                if (!string.IsNullOrWhiteSpace(user.Email))
                {
                    identity.AddClaim(CustomClaimTypes.Email, user.Email, OpenIdConnectConstants.Destinations.IdentityToken);
                }
            }

            if (ticket.HasScope(OpenIdConnectConstants.Scopes.Phone))
            {
                if (!string.IsNullOrWhiteSpace(user.PhoneNumber))
                {
                    identity.AddClaim(CustomClaimTypes.Phone, user.PhoneNumber, OpenIdConnectConstants.Destinations.IdentityToken);
                }
            }

            return(ticket);
        }
        /// <inheritdoc/>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            return(await Task.Run <AuthenticateResult>(() =>
            {
                if (!Request.Headers.ContainsKey("Authorization"))
                {
                    _responseHeader = "Bearer realm=\"token_required\"";
                    _responseResult = ErrorObjectResultFactory.NoAuthorizationHeader();
                    return AuthenticateResult.Fail(_responseResult.Error.Message);
                }

                var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
                if (authHeader.Scheme != "Bearer")
                {
                    _responseHeader = "Bearer error=\"invalid_request\"";
                    _responseResult = ErrorObjectResultFactory.InvalidAuthorizationScheme();
                    return AuthenticateResult.Fail(_responseResult.Error.Message);
                }

                try
                {
                    if (authHeader.Parameter == null)
                    {
                        _responseHeader = "Bearer error=\"invalid_token\"";
                        _responseResult = ErrorObjectResultFactory.InvalidAuthorizationToken();
                        return AuthenticateResult.Fail(_responseResult.Error.Message);
                    }

                    var accessToken = _authorizeService.GetAccessToken(authHeader.Parameter);
                    if (accessToken == null)
                    {
                        _responseHeader = "Bearer error=\"invalid_token\"";
                        _responseResult = ErrorObjectResultFactory.InvalidAuthorizationToken();
                        return AuthenticateResult.Fail(_responseResult.Error.Message);
                    }

                    if (accessToken.ExpiryTime < DateUtil.Now)
                    {
                        _responseHeader = "Bearer error=\"invalid_token\"";
                        _responseResult = ErrorObjectResultFactory.AuthorizationTokenExpired();
                        return AuthenticateResult.Fail(_responseResult.Error.Message);
                    }

                    var result = new List <Claim>();

                    foreach (var role in accessToken.Roles)
                    {
                        result.Add(new Claim(ClaimTypes.Role, role));
                    }

                    foreach (var scope in accessToken.Scopes)
                    {
                        result.Add(new Claim(Scopes.ClaimType, scope));
                    }

                    result.Add(new Claim(ClaimTypes.Name, accessToken.Name));
                    result.Add(new Claim(ClaimTypes.NameIdentifier, accessToken.PrincipalId.ToString()));

                    var identity = new ClaimsIdentity(result.ToArray(), Scheme.Name);
                    var principal = new ClaimsPrincipal(identity);
                    var ticket = new AuthenticationTicket(principal, Scheme.Name);

                    return AuthenticateResult.Success(ticket);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, ex.Message);
                    _responseResult = ErrorObjectResultFactory.InternalServerError();
                    return AuthenticateResult.Fail(_responseResult.Error.Message);
                }
            }));
        }
예제 #5
0
 public static void AuthenticationTicket(this HttpContext context, AuthenticationTicket ticket) =>
 context.Items.Add(AuthenticationTicketItemName, ticket);
 /// <summary>
 /// Replaces the ticket information on this context and marks it as as validated by the application.
 /// IsValidated becomes true and HasError becomes false as a result of calling.
 /// </summary>
 /// <param name="ticket">Assigned to the Ticket property</param>
 /// <returns>True if the validation has taken effect.</returns>
 public bool Validate(AuthenticationTicket ticket)
 {
     Ticket = ticket;
     return(Validate());
 }
예제 #7
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="context">OWIN environment</param>
 /// <param name="ticket">The authentication ticket</param>
 public WordPressReturnEndpointContext(
     IOwinContext context,
     AuthenticationTicket ticket)
     : base(context, ticket)
 {
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="context">OWIN environment</param>
 /// <param name="ticket">The authentication ticket</param>
 public EveOnlineReturnEndpointContext(
     IOwinContext context,
     AuthenticationTicket ticket)
     : base(context, ticket)
 {
 }
예제 #9
0
            protected override Task <AuthenticateResult> HandleAuthenticateAsync()
            {
                var authenticationTicket = new AuthenticationTicket(_principal, new AuthenticationProperties(), "TEST");

                return(Task.FromResult(AuthenticateResult.Success(authenticationTicket)));
            }
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            try
            {
                UnitOfWork unitOfWork  = new UnitOfWork();
                var        userManager = context.OwinContext.GetUserManager <ApplicationUserManager>();

                ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);



                if (user == null)
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect.");
                    return;
                }
                var roles = userManager.GetRoles(user.Id);
                var scope = context.Scope.ToList();
                var str   = context.Scope[0];

                var customerId = Convert.ToInt32(!str.Contains("*")?str:str.Split('*')[0]);
                var app        = !str.Contains("*")?"x": str.Split('*')[1];

                if (app == "ap")
                {
                    var ap_roles = roles.Where(q => q == "Admin" || q == "User").ToList();
                    if (ap_roles.Count == 0)
                    {
                        context.SetError("invalid_grant", "The user name or password is incorrect.");
                        return;
                    }
                }
                var employee = await unitOfWork.PersonRepository.GetViewEmployeesByUserId(user.Id, customerId);


                ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
                                                                                    OAuthDefaults.AuthenticationType);

                ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
                                                                                      CookieAuthenticationDefaults.AuthenticationType);

                oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
                oAuthIdentity.AddClaim(new Claim(ClaimTypes.Role, "user"));
                oAuthIdentity.AddClaim(new Claim("sub", context.UserName));
                oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, "Vahid"));

                AuthenticationProperties properties = CreateProperties(user.UserName, (context.ClientId == null) ? string.Empty : context.ClientId);
                if (employee != null)
                {
                    properties.Dictionary.Add("Name", employee.Name);
                    properties.Dictionary.Add("UserId", employee.PersonId.ToString());
                    properties.Dictionary.Add("EmployeeId", employee.Id.ToString());
                    properties.Dictionary.Add("Roles", string.Join(",", roles));
                }
                //if (employees.Count > 0)
                // {
                //     var customers =string.Join("_", employees.Select(q => q.CustomerId).Distinct().ToArray());
                //     var name = employees.First().Name;


                // }
                // properties.Dictionary.Add("Name", "Vahid Moghaddam");
                AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
                context.Validated(ticket);
                context.Request.Context.Authentication.SignIn(cookiesIdentity);
            }
            catch (Exception ex)
            {
                int i = 0;
            }
        }
예제 #11
0
        private async Task <bool> InvokeIntrospectionEndpointAsync()
        {
            OpenIdConnectMessage request;

            // See https://tools.ietf.org/html/rfc7662#section-2.1
            // and https://tools.ietf.org/html/rfc7662#section-4
            if (string.Equals(Request.Method, "GET", StringComparison.OrdinalIgnoreCase))
            {
                request = new OpenIdConnectMessage(Request.Query.ToDictionary())
                {
                    RequestType = OpenIdConnectRequestType.AuthenticationRequest
                };
            }

            else if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase))
            {
                // See http://openid.net/specs/openid-connect-core-1_0.html#FormSerialization
                if (string.IsNullOrEmpty(Request.ContentType))
                {
                    Logger.LogError("The introspection request was rejected because " +
                                    "the mandatory 'Content-Type' header was missing.");

                    return(await SendErrorPayloadAsync(new OpenIdConnectMessage {
                        Error = OpenIdConnectConstants.Errors.InvalidRequest,
                        ErrorDescription = "A malformed introspection request has been received: " +
                                           "the mandatory 'Content-Type' header was missing from the POST request."
                    }));
                }

                // May have media/type; charset=utf-8, allow partial match.
                if (!Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase))
                {
                    Logger.LogError("The introspection request was rejected because an invalid 'Content-Type' " +
                                    "header was received: {ContentType}.", Request.ContentType);

                    return(await SendErrorPayloadAsync(new OpenIdConnectMessage {
                        Error = OpenIdConnectConstants.Errors.InvalidRequest,
                        ErrorDescription = "A malformed introspection request has been received: " +
                                           "the 'Content-Type' header contained an unexcepted value. " +
                                           "Make sure to use 'application/x-www-form-urlencoded'."
                    }));
                }

                var form = await Request.ReadFormAsync(Context.RequestAborted);

                request = new OpenIdConnectMessage(form.ToDictionary())
                {
                    RequestType = OpenIdConnectRequestType.AuthenticationRequest
                };
            }

            else
            {
                Logger.LogError("The introspection request was rejected because an invalid " +
                                "HTTP method was received: {Method}.", Request.Method);

                return(await SendErrorPageAsync(new OpenIdConnectMessage {
                    Error = OpenIdConnectConstants.Errors.InvalidRequest,
                    ErrorDescription = "A malformed introspection request has been received: " +
                                       "make sure to use either GET or POST."
                }));
            }

            if (string.IsNullOrWhiteSpace(request.GetToken()))
            {
                return(await SendErrorPayloadAsync(new OpenIdConnectMessage {
                    Error = OpenIdConnectConstants.Errors.InvalidRequest,
                    ErrorDescription = "A malformed introspection request has been received: " +
                                       "a 'token' parameter with an access, refresh, or identity token is required."
                }));
            }

            // Insert the introspection request in the ASP.NET context.
            Context.SetOpenIdConnectRequest(request);

            // When client_id and client_secret are both null, try to extract them from the Authorization header.
            // See http://tools.ietf.org/html/rfc6749#section-2.3.1 and
            // http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication
            if (string.IsNullOrEmpty(request.ClientId) && string.IsNullOrEmpty(request.ClientSecret))
            {
                string header = Request.Headers[HeaderNames.Authorization];
                if (!string.IsNullOrEmpty(header) && header.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
                {
                    try {
                        var value = header.Substring("Basic ".Length).Trim();
                        var data  = Encoding.UTF8.GetString(Convert.FromBase64String(value));

                        var index = data.IndexOf(':');
                        if (index >= 0)
                        {
                            request.ClientId     = data.Substring(0, index);
                            request.ClientSecret = data.Substring(index + 1);
                        }
                    }

                    catch (FormatException) { }
                    catch (ArgumentException) { }
                }
            }

            var validatingContext = new ValidateIntrospectionRequestContext(Context, Options, request);
            await Options.Provider.ValidateIntrospectionRequest(validatingContext);

            if (validatingContext.IsRejected)
            {
                Logger.LogInformation("The introspection request was rejected by application code.");

                return(await SendErrorPayloadAsync(new OpenIdConnectMessage {
                    Error = validatingContext.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
                    ErrorDescription = validatingContext.ErrorDescription,
                    ErrorUri = validatingContext.ErrorUri
                }));
            }

            // Ensure that the client_id has been set from the ValidateIntrospectionRequest event.
            else if (validatingContext.IsValidated && string.IsNullOrEmpty(request.ClientId))
            {
                Logger.LogError("The introspection request was validated but the client_id was not set.");

                return(await SendErrorPayloadAsync(new OpenIdConnectMessage {
                    Error = OpenIdConnectConstants.Errors.ServerError,
                    ErrorDescription = "An internal server error occurred."
                }));
            }

            AuthenticationTicket ticket = null;

            // Note: use the "token_type_hint" parameter to determine
            // the type of the token sent by the client application.
            // See https://tools.ietf.org/html/rfc7662#section-2.1
            switch (request.GetTokenTypeHint())
            {
            case OpenIdConnectConstants.Usages.AccessToken:
                ticket = await DeserializeAccessTokenAsync(request.GetToken(), request);

                break;

            case OpenIdConnectConstants.Usages.RefreshToken:
                ticket = await DeserializeRefreshTokenAsync(request.GetToken(), request);

                break;

            case OpenIdConnectConstants.Usages.IdToken:
                ticket = await DeserializeIdentityTokenAsync(request.GetToken(), request);

                break;
            }

            // Note: if the token can't be found using "token_type_hint",
            // the search must be extended to all supported token types.
            // See https://tools.ietf.org/html/rfc7662#section-2.1
            if (ticket == null)
            {
                ticket = await DeserializeAccessTokenAsync(request.GetToken(), request) ??
                         await DeserializeIdentityTokenAsync(request.GetToken(), request) ??
                         await DeserializeRefreshTokenAsync(request.GetToken(), request);
            }

            if (ticket == null)
            {
                Logger.LogInformation("The introspection request was rejected because the token was invalid.");

                return(await SendPayloadAsync(new JObject {
                    [OpenIdConnectConstants.Claims.Active] = false
                }));
            }

            // Note: unlike refresh or identity tokens that can only be validated by client applications,
            // access tokens can be validated by either resource servers or client applications:
            // in both cases, the caller must be authenticated if the ticket is marked as confidential.
            if (validatingContext.IsSkipped && ticket.IsConfidential())
            {
                Logger.LogWarning("The introspection request was rejected because the caller was not authenticated.");

                return(await SendPayloadAsync(new JObject {
                    [OpenIdConnectConstants.Claims.Active] = false
                }));
            }

            // If the ticket is already expired, directly return active=false.
            if (ticket.Properties.ExpiresUtc.HasValue &&
                ticket.Properties.ExpiresUtc < Options.SystemClock.UtcNow)
            {
                Logger.LogInformation("The introspection request was rejected because the token was expired.");

                return(await SendPayloadAsync(new JObject {
                    [OpenIdConnectConstants.Claims.Active] = false
                }));
            }

            // When a client_id can be inferred from the introspection request,
            // ensure that the client application is a valid audience/presenter.
            if (!string.IsNullOrEmpty(request.ClientId))
            {
                // Ensure the caller is listed as a valid audience or authorized presenter.
                if (ticket.IsAccessToken() && ticket.HasAudience() && !ticket.HasAudience(request.ClientId) &&
                    ticket.HasPresenter() && !ticket.HasPresenter(request.ClientId))
                {
                    Logger.LogWarning("The introspection request was rejected because the access token " +
                                      "was issued to a different client or for another resource server.");

                    return(await SendPayloadAsync(new JObject {
                        [OpenIdConnectConstants.Claims.Active] = false
                    }));
                }

                // Reject the request if the caller is not listed as a valid audience.
                else if (ticket.IsIdentityToken() && ticket.HasAudience() && !ticket.HasAudience(request.ClientId))
                {
                    Logger.LogWarning("The introspection request was rejected because the " +
                                      "identity token was issued to a different client.");

                    return(await SendPayloadAsync(new JObject {
                        [OpenIdConnectConstants.Claims.Active] = false
                    }));
                }

                // Reject the introspection request if the caller doesn't
                // correspond to the client application the token was issued to.
                else if (ticket.IsRefreshToken() && ticket.HasPresenter() && !ticket.HasPresenter(request.ClientId))
                {
                    Logger.LogWarning("The introspection request was rejected because the " +
                                      "refresh token was issued to a different client.");

                    return(await SendPayloadAsync(new JObject {
                        [OpenIdConnectConstants.Claims.Active] = false
                    }));
                }
            }

            var notification = new HandleIntrospectionRequestContext(Context, Options, request, ticket);

            notification.Active = true;

            // Use the unique ticket identifier to populate the "jti" claim.
            notification.TokenId = ticket.GetTicketId();

            // Note: only set "token_type" when the received token is an access token.
            // See https://tools.ietf.org/html/rfc7662#section-2.2
            // and https://tools.ietf.org/html/rfc6749#section-5.1
            if (ticket.IsAccessToken())
            {
                notification.TokenType = OpenIdConnectConstants.TokenTypes.Bearer;
            }

            notification.Issuer  = Context.GetIssuer(Options);
            notification.Subject = ticket.Principal.GetClaim(ClaimTypes.NameIdentifier);

            notification.IssuedAt  = ticket.Properties.IssuedUtc;
            notification.ExpiresAt = ticket.Properties.ExpiresUtc;

            // Copy the audiences extracted from the "aud" claim.
            foreach (var audience in ticket.GetAudiences())
            {
                notification.Audiences.Add(audience);
            }

            // Note: non-metadata claims are only added if the caller is authenticated
            // AND is in the specified audiences, unless there's so explicit audience.
            if (!ticket.HasAudience() || (!string.IsNullOrEmpty(request.ClientId) && ticket.HasAudience(request.ClientId)))
            {
                // Extract the main identity associated with the principal.
                var identity = (ClaimsIdentity)ticket.Principal.Identity;

                notification.Username = identity.Name;
                notification.Scope    = ticket.GetProperty(OpenIdConnectConstants.Properties.Scopes);

                // Potentially sensitive claims are only exposed to trusted callers
                // if the ticket corresponds to an access or identity token.
                if (ticket.IsAccessToken() || ticket.IsIdentityToken())
                {
                    foreach (var claim in ticket.Principal.Claims)
                    {
                        // Exclude standard claims, that are already handled via strongly-typed properties.
                        // Make sure to always update this list when adding new built-in claim properties.
                        if (string.Equals(claim.Type, identity.NameClaimType, StringComparison.Ordinal) ||
                            string.Equals(claim.Type, ClaimTypes.NameIdentifier, StringComparison.Ordinal))
                        {
                            continue;
                        }

                        if (string.Equals(claim.Type, OpenIdConnectConstants.Claims.Audience, StringComparison.Ordinal) ||
                            string.Equals(claim.Type, OpenIdConnectConstants.Claims.ExpiresAt, StringComparison.Ordinal) ||
                            string.Equals(claim.Type, OpenIdConnectConstants.Claims.IssuedAt, StringComparison.Ordinal) ||
                            string.Equals(claim.Type, OpenIdConnectConstants.Claims.Issuer, StringComparison.Ordinal) ||
                            string.Equals(claim.Type, OpenIdConnectConstants.Claims.NotBefore, StringComparison.Ordinal) ||
                            string.Equals(claim.Type, OpenIdConnectConstants.Claims.Scope, StringComparison.Ordinal) ||
                            string.Equals(claim.Type, OpenIdConnectConstants.Claims.Subject, StringComparison.Ordinal) ||
                            string.Equals(claim.Type, OpenIdConnectConstants.Claims.TokenType, StringComparison.Ordinal))
                        {
                            continue;
                        }

                        string type;
                        // Try to resolve the short name associated with the claim type:
                        // if none can be found, the claim type is used as-is.
                        if (!JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.TryGetValue(claim.Type, out type))
                        {
                            type = claim.Type;
                        }

                        // Note: make sure to use the indexer
                        // syntax to avoid duplicate properties.
                        notification.Claims[type] = claim.Value;
                    }
                }
            }

            await Options.Provider.HandleIntrospectionRequest(notification);

            // Flow the changes made to the authentication ticket.
            ticket = notification.Ticket;

            if (notification.HandledResponse)
            {
                return(true);
            }

            else if (notification.Skipped)
            {
                return(false);
            }

            var payload = new JObject();

            payload.Add(OpenIdConnectConstants.Claims.Active, notification.Active);

            // Only add the other properties if
            // the token is considered as active.
            if (notification.Active)
            {
                if (!string.IsNullOrEmpty(notification.Issuer))
                {
                    payload.Add(OpenIdConnectConstants.Claims.Issuer, notification.Issuer);
                }

                if (!string.IsNullOrEmpty(notification.Username))
                {
                    payload.Add(OpenIdConnectConstants.Claims.Username, notification.Username);
                }

                if (!string.IsNullOrEmpty(notification.Subject))
                {
                    payload.Add(OpenIdConnectConstants.Claims.Subject, notification.Subject);
                }

                if (!string.IsNullOrEmpty(notification.Scope))
                {
                    payload.Add(OpenIdConnectConstants.Claims.Scope, notification.Scope);
                }

                if (notification.IssuedAt.HasValue)
                {
                    payload.Add(OpenIdConnectConstants.Claims.IssuedAt,
                                EpochTime.GetIntDate(notification.IssuedAt.Value.UtcDateTime));

                    payload.Add(OpenIdConnectConstants.Claims.NotBefore,
                                EpochTime.GetIntDate(notification.IssuedAt.Value.UtcDateTime));
                }

                if (notification.ExpiresAt.HasValue)
                {
                    payload.Add(OpenIdConnectConstants.Claims.ExpiresAt,
                                EpochTime.GetIntDate(notification.ExpiresAt.Value.UtcDateTime));
                }

                if (!string.IsNullOrEmpty(notification.TokenId))
                {
                    payload.Add(OpenIdConnectConstants.Claims.JwtId, notification.TokenId);
                }

                if (!string.IsNullOrEmpty(notification.TokenType))
                {
                    payload.Add(OpenIdConnectConstants.Claims.TokenType, notification.TokenType);
                }

                switch (notification.Audiences.Count)
                {
                case 0: break;

                case 1:
                    payload.Add(OpenIdConnectConstants.Claims.Audience, notification.Audiences[0]);
                    break;

                default:
                    payload.Add(OpenIdConnectConstants.Claims.Audience, JArray.FromObject(notification.Audiences));
                    break;
                }

                foreach (var claim in notification.Claims)
                {
                    // Ignore claims whose value is null.
                    if (claim.Value == null)
                    {
                        continue;
                    }

                    // Note: make sure to use the indexer
                    // syntax to avoid duplicate properties.
                    payload[claim.Key] = claim.Value;
                }
            }

            var context = new ApplyIntrospectionResponseContext(Context, Options, payload);
            await Options.Provider.ApplyIntrospectionResponse(context);

            if (context.HandledResponse)
            {
                return(true);
            }

            else if (context.Skipped)
            {
                return(false);
            }

            using (var buffer = new MemoryStream())
                using (var writer = new JsonTextWriter(new StreamWriter(buffer))) {
                    payload.WriteTo(writer);
                    writer.Flush();

                    Response.ContentLength = buffer.Length;
                    Response.ContentType   = "application/json;charset=UTF-8";

                    Response.Headers[HeaderNames.CacheControl] = "no-cache";
                    Response.Headers[HeaderNames.Pragma]       = "no-cache";
                    Response.Headers[HeaderNames.Expires]      = "-1";

                    buffer.Seek(offset: 0, loc: SeekOrigin.Begin);
                    await buffer.CopyToAsync(Response.Body, 4096, Context.RequestAborted);

                    return(true);
                }
        }
        public async Task <IActionResult> Exhange(OpenIdConnectRequest request)
        {
            if (request.IsPasswordGrantType())
            {
                //request.GrantType = "password";
                // Validate the user credentials.
                // Note: to mitigate brute force attacks, you SHOULD strongly consider
                // applying a key derivation function like PBKDF2 to slow down
                // the password validation process. You SHOULD also consider
                // using a time-constant comparer to prevent timing attacks.
                var bsonUser = await this.dbContext.GetUser(request.Username);

                var user = new PropyUser();
                if (bsonUser.Count == 0)
                {
                    user.Id            = Guid.NewGuid().ToString();
                    user.UserName      = "******";
                    user.PasswordHash  = "AnonPass";
                    user.SecurityStamp = Guid.NewGuid().ToString();
                }
                else
                {
                    user = new PropyUser()
                    {
                        Id            = bsonUser[0]["_id"].ToString(),
                        UserName      = bsonUser[0]["UserName"].ToString(),
                        PasswordHash  = bsonUser[0]["PasswordHash"].ToString(),
                        SecurityStamp = bsonUser[0]["SecurityStamp"].ToString()
                    };
                }

                // Check password hash
                var hasher             = new PasswordHasher <PropyUser>();
                var verificationResult = hasher.VerifyHashedPassword(user, user.PasswordHash, request.Password);
                //if (user.Username != "*****@*****.**" ||
                //    user.Password != "P@ssw0rd")
                //{
                //    return Forbid(OpenIdConnectServerDefaults.AuthenticationScheme);
                //}
                // Create a new ClaimsIdentity holding the user identity.
                var identity = new ClaimsIdentity(
                    OpenIdConnectServerDefaults.AuthenticationScheme,
                    OpenIdConnectConstants.Claims.Name,
                    OpenIdConnectConstants.Claims.Role);
                // Add a "sub" claim containing the user identifier, and attach
                // the "access_token" destination to allow OpenIddict to store it
                // in the access token, so it can be retrieved from your controllers.
                //identity.AddClaim(OpenIdConnectConstants.Claims.Subject,
                //    "71346D62-9BA5-4B6D-9ECA-755574D628D8",
                //    OpenIdConnectConstants.Destinations.AccessToken);
                //identity.AddClaim(OpenIdConnectConstants.Claims.Name, "Alice",
                //    OpenIdConnectConstants.Destinations.AccessToken);

                identity.AddClaim(OpenIdConnectConstants.Claims.Subject,
                                  user.Id,
                                  OpenIdConnectConstants.Destinations.AccessToken);
                identity.AddClaim(OpenIdConnectConstants.Claims.Name, user.UserName,
                                  OpenIdConnectConstants.Destinations.AccessToken);
                // ... add other claims, if necessary.
                var principal = new ClaimsPrincipal(identity);

                //var ticket = CreateTicket(request, principal);
                var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme);
                ticket.SetScopes(new[]
                {
                    OpenIdConnectConstants.Scopes.OpenId,
                    OpenIdConnectConstants.Scopes.Email,
                    OpenIdConnectConstants.Scopes.Profile,
                    OpenIdConnectConstants.Scopes.OfflineAccess,
                    //OpenIddictConstants.Scopes.Roles
                }.Intersect(request.GetScopes()));

                // Ask OpenIddict to generate a new token and return an OAuth2 token response.
                //return SignIn(principal, OpenIdConnectServerDefaults.AuthenticationScheme);
                return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
            }
            else if (request.IsRefreshTokenGrantType())
            {
                var info = await this.HttpContext.AuthenticateAsync(OpenIdConnectServerDefaults.AuthenticationScheme);

                // Create a new ClaimsIdentity holding the user identity.
                var identity = new ClaimsIdentity(
                    OpenIdConnectServerDefaults.AuthenticationScheme,
                    OpenIdConnectConstants.Claims.Name,
                    OpenIdConnectConstants.Claims.Role);
                // Add a "sub" claim containing the user identifier, and attach
                // the "access_token" destination to allow OpenIddict to store it
                // in the access token, so it can be retrieved from your controllers.
                identity.AddClaim(OpenIdConnectConstants.Claims.Subject,
                                  "71346D62-9BA5-4B6D-9ECA-755574D628D8",
                                  OpenIdConnectConstants.Destinations.AccessToken);
                identity.AddClaim(OpenIdConnectConstants.Claims.Name, "Alice",
                                  OpenIdConnectConstants.Destinations.AccessToken);
                // ... add other claims, if necessary.
                var principal = new ClaimsPrincipal(identity);

                var ticket = new AuthenticationTicket(principal, info.Properties,
                                                      OpenIdConnectServerDefaults.AuthenticationScheme);

                return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
            }
            else if (request.GrantType == "urn:ietf:params:oauth:grant-type:facebook_access_token")
            {
                var account = await this.facebookService.GetAccountAsync(request.Assertion);

                var bsonUser = await this.dbContext.GetUserByFacebookId(account.Id);

                PropyUser user;
                if (bsonUser.Count == 0)
                {
                    user = new PropyUser()
                    {
                        Id         = request.Assertion,
                        FacebookId = account.Id,
                        UserName   = account.Username,
                        FirstName  = account.FirstName,
                        LastName   = account.LastName,
                        Email      = account.Email
                    };

                    await this.dbContext.CreateUser(user);
                }
                else
                {
                    user = new PropyUser()
                    {
                        Id         = request.Assertion,
                        FacebookId = bsonUser[0]["facebookId"].ToString(),
                        UserName   = bsonUser[0]["UserName"].ToString(),
                        FirstName  = bsonUser[0]["firstName"].ToString(),
                        LastName   = bsonUser[0]["lastName"].ToString(),
                        Email      = bsonUser[0]["facebookId"].ToString(),
                    };
                }

                var identity = new ClaimsIdentity(
                    OpenIdConnectServerDefaults.AuthenticationScheme,
                    OpenIdConnectConstants.Claims.Name,
                    OpenIdConnectConstants.Claims.Role);

                identity.AddClaim(OpenIdConnectConstants.Claims.Subject,
                                  user.Id,
                                  OpenIdConnectConstants.Destinations.AccessToken);
                identity.AddClaim(OpenIdConnectConstants.Claims.Name, user.UserName,
                                  OpenIdConnectConstants.Destinations.AccessToken);

                var principal = new ClaimsPrincipal(identity);

                var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme);
                ticket.SetScopes(new[]
                {
                    OpenIdConnectConstants.Scopes.OfflineAccess,
                });

                return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
            }
            else if (request.GrantType == "urn:ietf:params:oauth:grant-type:google_identity_token")
            {
                // Exchange recieved Authorization Code for an access token
                var tokenUrl = "https://www.googleapis.com/oauth2/v4/token";

                //var code = "4/1VeXJLNmmH2dIYR8FSeW3OaVlYpK7BtZwVAhqzLvErk";
                var code          = request.Assertion;
                var client_id     = "295998800597-kao41iolosp6kl304dedl3u2551bogie.apps.googleusercontent.com";
                var client_secret = "z4VDv49a9aGMtQQK4NM8dZnn";
                var grant_type    = "authorization_code";
                var redirect_uri  = "http://localhost:5000";

                var data = new Dictionary <string, string>
                {
                    { "code", code },
                    { "client_id", client_id },
                    { "client_secret", client_secret },
                    { "grant_type", grant_type },
                    { "redirect_uri", redirect_uri }
                };

                var httpClient   = new HttpClient();
                var requestToken = new HttpRequestMessage(HttpMethod.Post, tokenUrl)
                {
                    Content = new FormUrlEncodedContent(data)
                };
                var response = await httpClient.SendAsync(requestToken);

                var responseContent = await response.Content.ReadAsStringAsync();

                var responseContentDeserializrd = JsonConvert.DeserializeObject <ResponseData>(responseContent);
                var accessToken = responseContentDeserializrd.AccessToken;

                // Use the access token to request the user's info
                httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken}");
                var userInfoUrl  = "https://www.googleapis.com/oauth2/v1/userinfo";
                var userResponse = await httpClient.GetAsync(userInfoUrl);

                var userResponseContent = await userResponse.Content.ReadAsStringAsync();

                var userInfo = JsonConvert.DeserializeObject <UserInfo>(userResponseContent);

                // Create user if one does not exist, and log him in
                var user     = new PropyUser();
                var bsonUser = await this.dbContext.GetUserByGoogleId(userInfo.Id);

                if (bsonUser.Count == 0)
                {
                    user.Id        = Guid.NewGuid().ToString();
                    user.Email     = userInfo.Email;
                    user.UserName  = userInfo.Name;
                    user.FirstName = userInfo.GivenName;
                    user.LastName  = userInfo.FamilyName;
                    user.GoogleId  = userInfo.Id;

                    await this.dbContext.CreateUser(user);
                }
                else
                {
                    user.Id        = Guid.NewGuid().ToString();
                    user.Email     = bsonUser[0]["email"].ToString();
                    user.UserName  = bsonUser[0]["UserName"].ToString();
                    user.FirstName = bsonUser[0]["firstName"].ToString();
                    user.LastName  = bsonUser[0]["lastName"].ToString();
                    user.GoogleId  = bsonUser[0]["googleId"].ToString();
                }

                // Create user's identity, a ticket and then sign him in
                var identity = new ClaimsIdentity(
                    OpenIdConnectServerDefaults.AuthenticationScheme,
                    OpenIdConnectConstants.Claims.Name,
                    OpenIdConnectConstants.Claims.Role);

                identity.AddClaim(OpenIdConnectConstants.Claims.Subject,
                                  user.Id,
                                  OpenIdConnectConstants.Destinations.AccessToken);
                identity.AddClaim(OpenIdConnectConstants.Claims.Name, user.UserName,
                                  OpenIdConnectConstants.Destinations.AccessToken);

                var principal = new ClaimsPrincipal(identity);

                var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme);
                ticket.SetScopes(new[]
                {
                    OpenIdConnectConstants.Scopes.OfflineAccess,
                });

                return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
            }

            return(BadRequest(new OpenIdConnectResponse
            {
                Error = OpenIdConnectConstants.Errors.UnsupportedGrantType,
                ErrorDescription = "The specified grant type is not supported."
            }));
        }
예제 #13
0
        protected override Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            var hasAuthToken = Request.Headers.TryGetValue(HeaderNames.Authorization, out var authorization);

            if (hasAuthToken)
            {
                var validUser = IsValidAuthToken(authorization);
                if (!validUser.Valid)
                {
                    dynamic error = new
                    {
                        Message = "Invalid auth key.",
                        Code    = StatusCodes.Status401Unauthorized
                    };
                    var res = new ReturnData <dynamic>()
                    {
                        Success = false,
                        Data    = error
                    };
                    throw new Exception(JsonConvert.SerializeObject(res));
                }

                if (validUser.role != Role.Admin)
                {
                    if (string.IsNullOrEmpty(validUser.AllowedPrivileges))
                    {
                        dynamic error = new
                        {
                            Message = "The group has not yet been assigned privileges, please contact admin",
                            Code    = StatusCodes.Status401Unauthorized
                        };
                        var res = new ReturnData <dynamic>()
                        {
                            Success = false,
                            Data    = error
                        };

                        var exeption = new Exception(JsonConvert.SerializeObject(res));
                        throw exeption;
                    }

                    string userRoute = Request.Path;
                    if (userRoute.ToLower().Contains("api"))
                    {
                        var route = userRoute.Substring(1) != null?userRoute.Substring(1) : "";

                        var rolesSplit = userRoute.Split('/');
                        if (userRoute.Contains('/') && userRoute.Split('/').Length > 2)
                        {
                            route = rolesSplit[2] + '/' + rolesSplit[3];
                        }
                        //route = route.Remove(route.Length - 1);
                        var action = _context.UserGroupPrivileges.FirstOrDefault(m => m.Action.ToLower() == route.ToLower());
                        if (action == null)
                        {
                            dynamic error = new
                            {
                                Message = "Rights not found, please contact admin",
                                Code    = StatusCodes.Status401Unauthorized
                            };
                            var res = new ReturnData <dynamic>()
                            {
                                Success = false,
                                Data    = error
                            };
                            throw new Exception(JsonConvert.SerializeObject(res));
                        }

                        var allowedPrivilegesCode = validUser.AllowedPrivileges.Split(",");
                        if (!allowedPrivilegesCode.Contains("016"))
                        {
                            validUser.AllowedPrivileges += ",016";
                        }
                        allowedPrivilegesCode = validUser.AllowedPrivileges.Split(",");

                        var isAllowed = allowedPrivilegesCode.Contains(action.Code);

                        if (!isAllowed)
                        {
                            dynamic error = new
                            {
                                Message = "Forbidden request",
                                Code    = StatusCodes.Status401Unauthorized
                            };
                            var res = new ReturnData <dynamic>()
                            {
                                Success = false,
                                Data    = error
                            };
                            throw new Exception(JsonConvert.SerializeObject(res));

                            //var error = new Exception("The group has not yet been assigned privileges, please contact admin");
                            //throw error;
                        }
                    }
                }
            }

            var identities = new List <ClaimsIdentity> {
                new ClaimsIdentity("custom auth type")
            };
            var ticket = new AuthenticationTicket(new ClaimsPrincipal(identities), Options.Scheme);
            var authedicationResults = Task.FromResult(AuthenticateResult.Success(ticket));

            return(authedicationResults);
        }
예제 #14
0
        private async Task <IActionResult> ExchangeClientCredentialsGrantType(OpenIdConnectRequest request)
        {
            // Note: client authentication is always enforced by OpenIddict before this action is invoked.
            var application = await _applicationManager.FindByClientIdAsync(request.ClientId);

            if (application == null)
            {
                return(BadRequest(new OpenIdConnectResponse
                {
                    Error = OpenIddictConstants.Errors.InvalidClient,
                    ErrorDescription = T["The specified 'client_id' parameter is invalid."]
                }));
            }

            var identity = new ClaimsIdentity(
                OpenIddictServerDefaults.AuthenticationScheme,
                OpenIddictConstants.Claims.Name,
                OpenIddictConstants.Claims.Role);

            identity.AddClaim(OpenIdConstants.Claims.EntityType, OpenIdConstants.EntityTypes.Application,
                              OpenIddictConstants.Destinations.AccessToken,
                              OpenIddictConstants.Destinations.IdentityToken);

            identity.AddClaim(OpenIddictConstants.Claims.Subject, request.ClientId,
                              OpenIddictConstants.Destinations.AccessToken,
                              OpenIddictConstants.Destinations.IdentityToken);

            identity.AddClaim(OpenIddictConstants.Claims.Name,
                              await _applicationManager.GetDisplayNameAsync(application),
                              OpenIddictConstants.Destinations.AccessToken,
                              OpenIddictConstants.Destinations.IdentityToken);

            // If the role service is available, add all the role claims
            // associated with the application roles in the database.
            var roleService = HttpContext.RequestServices.GetService <IRoleService>();

            foreach (var role in await _applicationManager.GetRolesAsync(application))
            {
                identity.AddClaim(identity.RoleClaimType, role,
                                  OpenIddictConstants.Destinations.AccessToken,
                                  OpenIddictConstants.Destinations.IdentityToken);

                if (roleService != null)
                {
                    foreach (var claim in await roleService.GetRoleClaimsAsync(role))
                    {
                        identity.AddClaim(claim.SetDestinations(
                                              OpenIdConnectConstants.Destinations.AccessToken,
                                              OpenIdConnectConstants.Destinations.IdentityToken));
                    }
                }
            }

            var ticket = new AuthenticationTicket(
                new ClaimsPrincipal(identity),
                new AuthenticationProperties(),
                OpenIddictServerDefaults.AuthenticationScheme);

            ticket.SetResources(await GetResourcesAsync(request.GetScopes()));

            return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
        }
예제 #15
0
        private async Task <AuthenticationTicket> CreateUserTicketAsync(
            ClaimsPrincipal principal, object application, object authorization,
            OpenIdConnectRequest request, AuthenticationProperties properties = null)
        {
            Debug.Assert(request.IsAuthorizationRequest() || request.IsTokenRequest(),
                         "The request should be an authorization or token request.");

            var identity = (ClaimsIdentity)principal.Identity;

            // Note: make sure this claim is not added multiple times (which may happen when the principal
            // was extracted from an authorization code or from a refresh token ticket is re-used as-is).
            if (string.IsNullOrEmpty(principal.FindFirst(OpenIdConstants.Claims.EntityType)?.Value))
            {
                identity.AddClaim(OpenIdConstants.Claims.EntityType, OpenIdConstants.EntityTypes.User,
                                  OpenIddictConstants.Destinations.AccessToken,
                                  OpenIddictConstants.Destinations.IdentityToken);
            }

            // Note: while ASP.NET Core Identity uses the legacy WS-Federation claims (exposed by the ClaimTypes class),
            // OpenIddict uses the newer JWT claims defined by the OpenID Connect specification. To ensure the mandatory
            // subject claim is correctly populated (and avoid an InvalidOperationException), it's manually added here.
            if (string.IsNullOrEmpty(principal.FindFirst(OpenIdConnectConstants.Claims.Subject)?.Value))
            {
                identity.AddClaim(new Claim(OpenIdConnectConstants.Claims.Subject, principal.GetUserIdentifier()));
            }

            // Create a new authentication ticket holding the user identity.
            var ticket = new AuthenticationTicket(principal, properties,
                                                  OpenIddictServerDefaults.AuthenticationScheme);

            if (request.IsAuthorizationRequest() || (!request.IsAuthorizationCodeGrantType() &&
                                                     !request.IsRefreshTokenGrantType()))
            {
                // Set the list of scopes granted to the client application.
                // Note: the offline_access scope must be granted
                // to allow OpenIddict to return a refresh token.
                ticket.SetScopes(request.GetScopes());
                ticket.SetResources(await GetResourcesAsync(request.GetScopes()));

                // If the request is an authorization request, automatically create
                // a permanent authorization to avoid requiring explicit consent for
                // future authorization or token requests containing the same scopes.
                if (authorization == null && request.IsAuthorizationRequest())
                {
                    authorization = await _authorizationManager.CreateAsync(
                        principal : ticket.Principal,
                        subject : principal.GetUserIdentifier(),
                        client : await _applicationManager.GetIdAsync(application),
                        type : OpenIddictConstants.AuthorizationTypes.Permanent,
                        scopes : ImmutableArray.CreateRange(ticket.GetScopes()),
                        properties : ImmutableDictionary.CreateRange(ticket.Properties.Items));
                }

                if (authorization != null)
                {
                    // Attach the authorization identifier to the authentication ticket.
                    ticket.SetInternalAuthorizationId(await _authorizationManager.GetIdAsync(authorization));
                }
            }

            // Note: by default, claims are NOT automatically included in the access and identity tokens.
            // To allow OpenIddict to serialize them, you must attach them a destination, that specifies
            // whether they should be included in access tokens, in identity tokens or in both.

            foreach (var claim in ticket.Principal.Claims)
            {
                // Never include the security stamp in the access and identity tokens, as it's a secret value.
                if (claim.Type == "AspNet.Identity.SecurityStamp")
                {
                    continue;
                }

                var destinations = new List <string>
                {
                    OpenIddictConstants.Destinations.AccessToken
                };

                // Only add the iterated claim to the id_token if the corresponding scope was granted to the client application.
                // The other claims will only be added to the access_token, which is encrypted when using the default format.
                if ((claim.Type == OpenIddictConstants.Claims.Name && ticket.HasScope(OpenIddictConstants.Scopes.Profile)) ||
                    (claim.Type == OpenIddictConstants.Claims.Email && ticket.HasScope(OpenIddictConstants.Scopes.Email)) ||
                    (claim.Type == OpenIddictConstants.Claims.Role && ticket.HasScope(OpenIddictConstants.Claims.Roles)) ||
                    (claim.Type == OpenIdConstants.Claims.EntityType))
                {
                    destinations.Add(OpenIddictConstants.Destinations.IdentityToken);
                }

                claim.SetDestinations(destinations);
            }

            return(ticket);
        }
예제 #16
0
    /// <summary>
    /// Creates a new instance of the context object.
    /// </summary>
    /// <param name="context"></param>
    /// <param name="scheme"></param>
    /// <param name="ticket">Contains the initial values for identity and extra data</param>
    /// <param name="options"></param>
    public CookieValidatePrincipalContext(HttpContext context, AuthenticationScheme scheme, CookieAuthenticationOptions options, AuthenticationTicket ticket)
        : base(context, scheme, options, ticket?.Properties)
    {
        if (ticket == null)
        {
            throw new ArgumentNullException(nameof(ticket));
        }

        Principal = ticket.Principal;
    }
예제 #17
0
        public async Task <IActionResult> Accept(CancellationToken cancellationToken)
        {
            var response = HttpContext.GetOpenIdConnectResponse();

            if (response != null)
            {
                return(View("Error", response));
            }

            var request = HttpContext.GetOpenIdConnectRequest();

            if (request == null)
            {
                return(View("Error", new OpenIdConnectResponse {
                    Error = OpenIdConnectConstants.Errors.ServerError,
                    ErrorDescription = "An internal error has occurred"
                }));
            }

            // Create a new ClaimsIdentity containing the claims that
            // will be used to create an id_token, a token or a code.
            var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);

            // Copy the claims retrieved from the external identity provider
            // (e.g Google, Facebook, a WS-Fed provider or another OIDC server).
            foreach (var claim in HttpContext.User.Claims)
            {
                // Allow ClaimTypes.Name to be added in the id_token.
                // ClaimTypes.NameIdentifier is automatically added, even if its
                // destination is not defined or doesn't include "id_token".
                // The other claims won't be visible for the client application.
                if (claim.Type == ClaimTypes.Name)
                {
                    claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken,
                                          OpenIdConnectConstants.Destinations.IdentityToken);
                }

                identity.AddClaim(claim);
            }

            var application = await GetApplicationAsync(request.ClientId, cancellationToken);

            if (application == null)
            {
                return(View("Error", new OpenIdConnectResponse {
                    Error = OpenIdConnectConstants.Errors.InvalidClient,
                    ErrorDescription = "Details concerning the calling client application cannot be found in the database"
                }));
            }

            // Create a new ClaimsIdentity containing the claims associated with the application.
            // Note: setting identity.Actor is not mandatory but can be useful to access
            // the whole delegation chain from the resource server (see ResourceController.cs).
            identity.Actor = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
            identity.Actor.AddClaim(ClaimTypes.NameIdentifier, application.ApplicationID);

            identity.Actor.AddClaim(ClaimTypes.Name, application.DisplayName,
                                    OpenIdConnectConstants.Destinations.AccessToken,
                                    OpenIdConnectConstants.Destinations.IdentityToken);

            // Create a new authentication ticket holding the user identity.
            var ticket = new AuthenticationTicket(
                new ClaimsPrincipal(identity),
                new AuthenticationProperties(),
                OpenIdConnectServerDefaults.AuthenticationScheme);

            // Set the list of scopes granted to the client application.
            // Note: this sample always grants the "openid", "email" and "profile" scopes
            // when they are requested by the client application: a real world application
            // would probably display a form allowing to select the scopes to grant.
            ticket.SetScopes(new[] {
                /* openid: */ OpenIdConnectConstants.Scopes.OpenId,
                /* email: */ OpenIdConnectConstants.Scopes.Email,
                /* profile: */ OpenIdConnectConstants.Scopes.Profile,
                /* offline_access: */ OpenIdConnectConstants.Scopes.OfflineAccess
            }.Intersect(request.GetScopes()));

            // Set the resources servers the access token should be issued for.
            ticket.SetResources("resource_server");

            // Returning a SignInResult will ask ASOS to serialize the specified identity to build appropriate tokens.
            // Note: you should always make sure the identities you return contain ClaimTypes.NameIdentifier claim.
            // In this sample, the identity always contains the name identifier returned by the external provider.
            return(SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme));
        }
예제 #18
0
 private byte[] SerializeToBytes(AuthenticationTicket source)
 => TicketSerializer.Default.Serialize(source);
예제 #19
0
 public string Protect(AuthenticationTicket data, string purpose)
 {
     throw new NotImplementedException();
 }
예제 #20
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="context">OWIN environment</param>
 /// <param name="ticket">The authentication ticket</param>
 public BitbucketReturnEndpointContext(
     IOwinContext context,
     AuthenticationTicket ticket)
     : base(context, ticket)
 {
 }
예제 #21
-1
 public ReturnEndpointContext(
     IDictionary<string, object> environment,
     AuthenticationTicket ticket,
     IDictionary<string, string> errorDetails)
     : base(environment)
 {
     ErrorDetails = errorDetails;
     if (ticket != null)
     {
         Identity = ticket.Identity;
         Extra = ticket.Extra;
     }
 }
예제 #22
-1
        public void NullPrincipalThrows()
        {
            var properties = new AuthenticationProperties();
            properties.RedirectUri = "bye";
            var ticket = new AuthenticationTicket(properties, "Hello");

            using (var stream = new MemoryStream())
            using (var writer = new BinaryWriter(stream))
            using (var reader = new BinaryReader(stream))
            {
                Assert.Throws<ArgumentNullException>(() => TicketSerializer.Write(writer, ticket));
            }
        }
 public AuthenticationTokenCreateContext(
     IOwinContext context,
     ISecureDataFormat<AuthenticationTicket> secureDataFormat,
     AuthenticationTicket ticket)
     : base(context)
 {
     if (secureDataFormat == null)
     {
         throw new ArgumentNullException("secureDataFormat");
     }
     if (ticket == null)
     {
         throw new ArgumentNullException("ticket");
     }
     _secureDataFormat = secureDataFormat;
     Ticket = ticket;
 }
예제 #24
-1
        public void CanRoundTripEmptyPrincipal()
        {
            var properties = new AuthenticationProperties();
            properties.RedirectUri = "bye";
            var ticket = new AuthenticationTicket(new ClaimsPrincipal(), properties, "Hello");

            using (var stream = new MemoryStream())
            using (var writer = new BinaryWriter(stream))
            using (var reader = new BinaryReader(stream))
            {
                TicketSerializer.Write(writer, ticket);
                stream.Position = 0;
                var readTicket = TicketSerializer.Read(reader);
                readTicket.Principal.Identities.Count().ShouldBe(0);
                readTicket.Properties.RedirectUri.ShouldBe("bye");
                readTicket.AuthenticationScheme.ShouldBe("Hello");
            }
        }
        /// <summary>
        /// Creates a new instance of the context object.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ticket">Contains the initial values for identity and extra data</param>
        /// <param name="options"></param>
        public CookieValidatePrincipalContext(HttpContext context, AuthenticationTicket ticket, CookieAuthenticationOptions options)
            : base(context, options)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (ticket == null)
            {
                throw new ArgumentNullException(nameof(ticket));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            Principal = ticket.Principal;
            Properties = ticket.Properties;
        }
예제 #26
-1
        /// <summary>
        /// Initializes a new <see cref="OAuthCreatingTicketContext"/>.
        /// </summary>
        /// <param name="ticket">The <see cref="AuthenticationTicket"/>.</param>
        /// <param name="context">The HTTP environment.</param>
        /// <param name="options">The options used by the authentication middleware.</param>
        /// <param name="backchannel">The HTTP client used by the authentication middleware</param>
        /// <param name="tokens">The tokens returned from the token endpoint.</param>
        /// <param name="user">The JSON-serialized user.</param>
        public OAuthCreatingTicketContext(
            AuthenticationTicket ticket,
            HttpContext context,
            OAuthOptions options,
            HttpClient backchannel,
            OAuthTokenResponse tokens,
            JObject user)
            : base(context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (backchannel == null)
            {
                throw new ArgumentNullException(nameof(backchannel));
            }

            if (tokens == null)
            {
                throw new ArgumentNullException(nameof(tokens));
            }

            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            TokenResponse = tokens;
            Backchannel = backchannel;
            User = user;
            Options = options;
            Ticket = ticket;
        }
 /// <summary>
 /// Initializes a new <see cref="MicrosoftAccountReturnEndpointContext"/>.
 /// </summary>
 /// <param name="context">OWIN environment</param>
 /// <param name="ticket">The authentication ticket</param>
 public MicrosoftAccountReturnEndpointContext(
     IOwinContext context,
     AuthenticationTicket ticket)
     : base(context, ticket)
 {
 }
예제 #28
-1
 public FormsValidateIdentityContext(AuthenticationTicket ticket)
 {
     Identity = ticket.Identity;
     Extra = ticket.Extra;
 }
 public void DeserializeTicket(string protectedData)
 {
     Ticket = _secureDataFormat.Unprotect(protectedData);
 }
 /// <summary>
 /// Initializes a new <see cref="TwitterReturnEndpointContext"/>.
 /// </summary>
 /// <param name="context">HTTP environment</param>
 /// <param name="ticket">The authentication ticket</param>
 public TwitterReturnEndpointContext(
     HttpContext context,
     AuthenticationTicket ticket)
     : base(context, ticket)
 {
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="context">OWIN environment</param>
 /// <param name="ticket">The authentication ticket</param>
 public FacebookReturnEndpointContext(
     IOwinContext context,
     AuthenticationTicket ticket)
     : base(context, ticket)
 {
 }
 /// <summary>
 /// Initialize a <see cref="GoogleOAuth2ReturnEndpointContext"/>
 /// </summary>
 /// <param name="context">OWIN environment</param>
 /// <param name="ticket">The authentication ticket</param>
 public GoogleOAuth2ReturnEndpointContext(
     IOwinContext context,
     AuthenticationTicket ticket)
     : base(context, ticket)
 {
 }
 public SinaWeiboAccountReturnEndpointContext(
     IOwinContext context,
     AuthenticationTicket ticket)
     : base(context, ticket)
 {
 }
 protected override Task<AuthenticationTicket> GetUserInformationAsync(OpenIdConnectMessage message, JwtSecurityToken jwt, AuthenticationTicket ticket)
 {
     var claimsIdentity = (ClaimsIdentity)ticket.Principal.Identity;
     if (claimsIdentity == null)
     {
         claimsIdentity = new ClaimsIdentity();
     }
     claimsIdentity.AddClaim(new Claim("test claim", "test value"));
     return Task.FromResult(new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity), ticket.Properties, ticket.AuthenticationScheme));
 }
예제 #35
-2
 protected ReturnEndpointContext(
     HttpContext context,
     AuthenticationTicket ticket)
     : base(context)
 {
     if (ticket != null)
     {
         Principal = ticket.Principal;
         Properties = ticket.Properties;
     }
 }
예제 #36
-2
 protected ReturnEndpointContext(
     IOwinContext context,
     AuthenticationTicket ticket)
     : base(context)
 {
     if (ticket != null)
     {
         Identity = ticket.Identity;
         Properties = ticket.Properties;
     }
 }
 public ReturnEndpointContext(
     IDictionary<string, object> environment,
     AuthenticationTicket ticket)
     : base(environment)
 {
     Identity = ticket.Identity;
     Extra = ticket.Extra;
 }
 protected override async Task<AuthenticationTicket> GetUserInformationAsync(AuthenticationProperties properties, OpenIdConnectMessage message, AuthenticationTicket ticket)
 {
     var claimsIdentity = (ClaimsIdentity)ticket.Principal.Identity;
     if (claimsIdentity == null)
     {
         claimsIdentity = new ClaimsIdentity();
     }
     claimsIdentity.AddClaim(new Claim("test claim", "test value"));
     return new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity), ticket.Properties, ticket.AuthenticationScheme);
 }
예제 #39
-7
 public TwitterReturnEndpointContext(
     IDictionary<string, object> environment,
     AuthenticationTicket ticket,
     IDictionary<string, string> errorDetails)
     : base(environment, ticket, errorDetails)
 {
 }
 public void SetTicket(AuthenticationTicket ticket)
 {
     if (ticket == null)
     {
         throw new ArgumentNullException("ticket");
     }
     Ticket = ticket;
 }
예제 #41
-7
 /// <summary>
 /// Initializes a new <see cref="OAuthCreatingTicketContext"/>.
 /// </summary>
 /// <param name="ticket">The <see cref="AuthenticationTicket"/>.</param>
 /// <param name="context">The HTTP environment.</param>
 /// <param name="options">The options used by the authentication middleware.</param>
 /// <param name="backchannel">The HTTP client used by the authentication middleware</param>
 /// <param name="tokens">The tokens returned from the token endpoint.</param>
 public OAuthCreatingTicketContext(
     AuthenticationTicket ticket,
     HttpContext context,
     OAuthOptions options,
     HttpClient backchannel,
     OAuthTokenResponse tokens)
     : this(ticket, context, options, backchannel, tokens, user: new JObject())
 {
 }
예제 #42
-10
 public OAuthTokenEndpointContext(
     IDictionary<string, object> environment,
     AuthenticationTicket ticket,
     AccessTokenRequest accessTokenRequest) : base(environment)
 {
     Identity = ticket.Identity;
     Extra = ticket.Extra;
     AccessTokenRequest = accessTokenRequest;
     TokenIssued = Identity != null;
 }
        public void Persist(AuthenticationTicket ticket)
        {
            var cookie = _cookies.CreateCookie(_systemTime);
            cookie.Value = _encryptor.Encrypt(JsonUtil.ToJson(ticket));

            _cookies.Update(cookie);
        }