Microsoft Owin UseJwt

时间:2014-08-02 14:53:46

标签: authentication azure asp.net-web-api acs jwt

我使用UseJwtBearerAuthentication方法遇到困难,我使用Microsoft Azure ACS获取令牌(使用服务标识)。 JWT令牌可以很好地返回我的测试程序。在测试程序中,令牌被发送到MVC WebAPI 2.(从Azure Active Directory获取令牌时,WAAD身份验证正常工作)

public partial class Startup
{
    private const string Issuer = "https://bluebeam-us-east.accesscontrol.windows.net/";
    public void ConfigureAuth(IAppBuilder app)
    {
        string CertificateThumbprint = "99B25E3E31FCD24F669C260A743FBD508D21FE30";
        var audience = ConfigurationManager.AppSettings["ida:Audience"];
        app.UseErrorPage(new ErrorPageOptions()
                {
                    ShowEnvironment = true,
                    ShowCookies = false, 
         ShowSourceCode = true,
                    });



        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Audience =  audience ,
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"]
            });
        app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
        {
            AllowedAudiences = new[] { audience },
            IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
            {
                new X509CertificateSecurityTokenProvider(Issuer, X509CertificateHelper.FindByThumbprint(StoreName.My,StoreLocation.LocalMachine,CertificateThumbprint).First())
            },
        });
    }

从ACS获取令牌的代码如下:

private async void GetJwtToken()
{
    try
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri(IdP.Authority);
            var content = new FormUrlEncodedContent(new Dictionary<String, String>
            {
                {"grant_type","client_credentials"},
                {"client_id", IdP.UserName},
                {"client_secret", IdP.Password},
                {"scope", IdP.Resource}
            });
            var response = await client.PostAsync("v2/OAuth2-13", content);
            response.EnsureSuccessStatusCode();
            var jwtdata = await response.Content.ReadAsStringAsync();
            var jwt = JsonConvert.DeserializeObject<Token>(jwtdata);
            AccessToken = jwt.access_token;
            TokenType = jwt.token_type;
            long expire;
            if (long.TryParse(jwt.expires_in, out expire))
            {
                ExpiresOn = DateTimeOffset.UtcNow.AddSeconds(expire);
            }
            Authorization = AccessToken;
        }
    }
    catch (HttpRequestException re)
    {
        Response = re.Message;
    }
}

请求资源的代码(WebAPI):

private async void WebApiRequestCall()
    {
        try
        {
            ConfigureSsl();
            using (var client = new HttpClient())
            {
                client.BaseAddress = _baseAddress;
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                if (!String.IsNullOrWhiteSpace(Authorization))
                    client.DefaultRequestHeaders.Add("Authorization", Authorization);
                var response = await client.GetAsync(WebApiRequest);
                response.EnsureSuccessStatusCode();
                Response = await response.Content.ReadAsStringAsync();
            }
        }
        catch (HttpRequestException e)
        {
            Response = e.Message;
        }
    }

解码后的令牌(使用谷歌令牌解码器如下所示)

Header
{
    "x5t": "mbJePjH80k9mnCYKdD-9UI0h_jA", 
    "alg": "RS256", 
    "typ": "JWT"
}
Claims
{
    "identityprovider": "https://bluebeam-us-east.accesscontrol.windows.net/", 
    "iss": "https://bluebeam-us-east.accesscontrol.windows.net/", 
    "http://schemas.microsoft.com/identity/claims/identityprovider": "revu", 
    "exp": 1406957036, 
    "nbf": 1406956676, 
    "aud": "https://bluebeam.com/Bluebeam.Licensing.WebApi/"
}

所以我有以下问题:

1)使用JwtBearerToken正确的方法来解码来自ACS的解码JWT令牌 2)Owin中是否有任何跟踪设施可以提供认证管道中的哪些内容?

我使用的是Microsoft Own 3.0-rc1。

1 个答案:

答案 0 :(得分:3)

我的代码中似乎有一个错误,我没有设置正确的&#34; bearer header&#34;在向WebAPI发送客户端请求时为OWIN。

从ACS接收JWT令牌后,我需要正确设置授权

private async void GetJwtToken()
    {
        try
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(IdP.Authority);
                var content = new FormUrlEncodedContent(new Dictionary<String, String>
                {
                    {"grant_type","client_credentials"},
                    {"client_id", IdP.UserName},
                    {"client_secret", IdP.Password},
                    {"scope", IdP.Resource}
                });
                var response = await client.PostAsync("v2/OAuth2-13", content);
                response.EnsureSuccessStatusCode();
                var jwtdata = await response.Content.ReadAsStringAsync();
                var jwt = JsonConvert.DeserializeObject<Token>(jwtdata);
                IdP.AccessToken = jwt.access_token;
                IdP.TokenType = jwt.token_type;
                long expire;
                if (long.TryParse(jwt.expires_in, out expire))
                {
                    IdP.ExpiresOn = DateTimeOffset.UtcNow.AddSeconds(expire);
                }
                // Ensure that Correct Authorization Header for Owin
                Authorization = String.Format("{0} {1}", "Bearer", IdP.AccessToken);**
            }
        }
        catch (HttpRequestException re)
        {
            Response = re.Message;
        }
    }

我们还需要支持WebAPI上的对称密钥,具体取决于ACS如何发送令牌

public void ConfigureAuth(IAppBuilder app)
    {
        var thumbPrint = ConfigurationManager.AppSettings["ida:Thumbprint"];
        var audience = ConfigurationManager.AppSettings["ida:Audience"];
        var trustedTokenPolicyKey = ConfigurationManager.AppSettings["ida:SymmetricKey"];

        app.UseErrorPage(new ErrorPageOptions()
                {
                    ShowEnvironment = true,
                    ShowCookies = false,
                    ShowSourceCode = true,
                });

        app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions()
        {
            AllowedAudiences = new[] {audience},
            IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
            {
                new X509CertificateSecurityTokenProvider(Issuer,
                    X509CertificateHelper.FindByThumbprint(StoreName.My, StoreLocation.LocalMachine, thumbPrint)
                        .First()),
                new SymmetricKeyIssuerSecurityTokenProvider(Issuer, trustedTokenPolicyKey),
            },
        });
        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Audience = audience,
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"]
            });
    }