Как добавить пользовательские претензии в asp.net, содержащие службу внешней аутентификации? - PullRequest
0 голосов
/ 28 января 2019

Я настраиваю новый проект dotnet с OpenId-Connect и базовой аутентификацией Cookie.Токен, который я получаю от какого-либо сервера аутентификации (например, Azure Ad), основан на симметричном RS256.У меня два вопроса:

1-й Как добавить пользовательские переменные в токене, который находится в RS256.

2nd Как сохранить их в cookie?

Я пробовал с JWT.Serializer, но всегда застрял в той или иной точке.

    IJsonSerializer serializer = new JsonNetSerializer();
    IDateTimeProvider provider = new UtcDateTimeProvider();
    IJwtValidator validator = new JwtValidator(serializer, provider);
    IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
    var algo = new JWT.Algorithms.RSAlgorithmFactory(() => new 
    Class1().GetByThumbprint("C11B7AF7C7910DEEB2273996BAB6033D73F6DC61"));
    IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algo);

Незнаю, стоит ли продолжать с этим.Также с HS256 было легко редактировать токен на https://jwt.io/ Я не могу сделать это с RS256.

Startup.Auth.cs

public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(
        new CookieAuthenticationOptions()
        {
            AuthenticationMode = AuthenticationMode.Active,
            LoginPath = Microsoft.Owin.PathString.FromUriComponent("/Account/SignIn")
        });

    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
            ClientId = clientId,
            Authority = authority,
            PostLogoutRedirectUri = postLogoutRedirectUri,
        });
}

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Нашли решение.

1-й Как добавить пользовательские переменные в токен, который находится в RS256.

Вам не нужно.Токены, полученные от внешней службы с OpenId connect, в основном для аутентификации, а не для авторизации.Мы можем использовать несколько внешних служб аутентификации, добавление пользовательских утверждений здесь не будет хорошей идеей, и это также не должно быть сделано.

2nd Как сохранить их в cookie?

Это место быломы можем изменить наш токен.Cookie не находится в том же симметричном шифре, что и внешний сервис аутентификации.Мы можем перехватить метод проверки подлинности cookie, чтобы добавить пользовательские утверждения.

Вот как я это сделал:

CustomSecureDataFormat.cs

public class CustomSecureDataFormat : ISecureDataFormat<AuthenticationTicket>
{
    public string Protect(AuthenticationTicket data)
    {
        if (data == null)
        {
            throw new ArgumentNullException("data");
        }
        var claims = new List<Claim>();
        //Custom claim
        claims.Add(new Claim("HairCount", "46"));
        data.Identity.AddClaims(claims);
        string audienceId = AzureADConstants.GraphResourceId;
        Guid guidClientId;
        bool isValidAudience = Guid.TryParse(AzureADConstants.ClientId, out guidClientId);
        if (!isValidAudience)
        {
            throw new InvalidOperationException("AuthenticationTicket.Properties does not include audience");
        }

        var keyByteArray = TextEncodings.Base64Url.Decode(AzureADConstants.AppKey);
        var securityKey = new SymmetricSecurityKey(keyByteArray);
        var signingCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(
            securityKey,
            SecurityAlgorithms.HmacSha256Signature);

        var issued = data.Properties.IssuedUtc;
        var expires = data.Properties.ExpiresUtc;
        string _issuer = AzureADConstants.Authority;
        var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingCredentials);
        var handler = new JwtSecurityTokenHandler();
        return handler.WriteToken(token);
    }

    public AuthenticationTicket Unprotect(string protectedText)
    {
        if (string.IsNullOrWhiteSpace(protectedText))
        {
            throw new ArgumentNullException("protectedText");
        }

        var keyByteArray = TextEncodings.Base64Url.Decode(AzureADConstants.AppKey);
        var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(keyByteArray);
        var signingCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(
            securityKey,
            SecurityAlgorithms.HmacSha256Signature);

        var handler = new JwtSecurityTokenHandler();
        var securityToken = handler.ReadToken(protectedText);
        string rawToken = ((JwtSecurityToken)securityToken).RawData;

        string audienceId = AzureADConstants.GraphResourceId;

        var validationParams = new TokenValidationParameters()
        {
            ValidateLifetime = false,
            ValidAudience = audienceId,
            ValidIssuer = audienceId,
            ValidateIssuer = false,
            ValidateAudience = false,
            TokenDecryptionKey = securityKey,
            IssuerSigningKey = securityKey
        };
        SecurityToken validatedToken;
        var principal = handler.ValidateToken(rawToken, validationParams, out validatedToken);
        var identity = principal.Identities;

        return new AuthenticationTicket(identity.First(), new AuthenticationProperties());
    }
}

Startup.Auth.cs

app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
    AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
    LoginPath = Microsoft.Owin.PathString.FromUriComponent("/Account/SignIn"),
    TicketDataFormat = new CustomSecureDataFormat()
});
0 голосов
/ 28 января 2019

Для первого вопроса,

private string GenerateAccessJwt()
{
    JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();       

    SigningCredentials credentials = new SigningCredentials("your sign key", SecurityAlgorithms.RsaSha256);

    JwtSecurityToken token = new JwtSecurityToken(
        issuer: "Your issuer",
        audience: "Your audience",
        claims: new List<Claim>()
        {
            new Claim("OneClaim", "Hey I am a custom claim."),
        },
        expires: DateTime.Now.AddMinutes(1) //Short expiration for access token,
        signingCredentials: credentials);

    return handler.WriteToken(token);
}

Этот фрагмент должен помочь, вы должны использовать https://docs.microsoft.com/en-us/previous-versions/visualstudio/dn464181(v%3Dvs.114)

Работает для меня на NET Standard 2.0.

Надеюсь, это поможет.

...