使用Live Id从Universal App登录到Web Api

时间:2015-03-03 04:15:18

标签: asp.net asp.net-web-api windows-phone-8.1 liveid

我正在尝试实现以下功能:

  1. 用户从Windows Phone 8.1(或通用)应用登录Live ID帐户。
  2. App访问我使用ASP.NET Web Api 2开发的Web Api
  3. 在此Web Api中,我需要对用户进行身份验证。
  4. 稍后,我想在网络应用中验证相同的用户
  5. 这是我正在做的事情,但它不起作用。

    在我的Windows Phone应用程序中:

    var authClient = new LiveAuthClient("http://myservice.cloudapp.net");
    LiveLoginResult result = await authClient.LoginAsync(new string[] { "wl.signin" });
    
    if (result.Status == LiveConnectSessionStatus.Connected)
    {
        connected = true;
        var identity = await ConnectToApi(result.Session.AuthenticationToken);
        Debug.WriteLine(identity);
    }
    

    然后

    private async Task<string> ConnectToApi(string token)
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://myservice.cloudapp.net/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    
            // HTTP GET
            HttpResponseMessage response = await client.GetAsync("api/values");
            if (response.IsSuccessStatusCode)
            {
                string result = await response.Content.ReadAsStringAsync();
                return result;
            }
            else
                return response.ReasonPhrase;
        }
    }
    

    然后在我的网络API中我有以下

    public void ConfigureAuth(IAppBuilder app)
    {
    
        app.UseMicrosoftAccountAuthentication(
            clientId: "my client id",
            clientSecret: "my secret");
    
    }
    

    我将http://myservice.cloudapp.net注册为重定向网址。

    问题是身份验证不起作用,web api操作无法识别用户。

2 个答案:

答案 0 :(得分:3)

我完全错了。首先,我实际上需要使用app.UseJwtBearerAuthentication方法。这个例子在http://code.lawrab.com/2014/01/securing-webapi-with-live-id.html找到了。但是当我尝试时,我在输出中得到了这个错误

IDX10500: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier ( IsReadOnly = False, Count = 1, Clause[0] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause )

这个让我花了一些时间来弄明白,直到我找到这篇文章:JwtSecurityTokenHandler 4.0.0 Breaking Changes?

把这些东西放在一起,我得到的解决方案现在似乎在我的测试环境中起作用了:

public void ConfigureAuth(IAppBuilder app)
    {
        var sha256 = new SHA256Managed();
        var sKey = "<Secret key>" + "JWTSig";
        var secretBytes = new UTF8Encoding(true, true).GetBytes(sKey);
        var signingKey = sha256.ComputeHash(secretBytes);
        var securityKeyProvider = new SymmetricKeyIssuerSecurityTokenProvider("urn:windows:liveid", signingKey);
        var securityKey = securityKeyProvider.SecurityTokens.First().SecurityKeys.First();

        var jwtOptions = new JwtBearerAuthenticationOptions()
        {
            //AllowedAudiences = new[] { "<url>" },
            //IssuerSecurityTokenProviders = new[] 
            //{ 
            //  new SymmetricKeyIssuerSecurityTokenProvider("urn:windows:liveid",signingKey)
            //},
            TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters()
            {
                IssuerSigningKeyResolver = (token, securityToken, keyIdentifier, validationParameters) =>
                    {
                        return securityKey;
                    },
                ValidAudience = "<url>",
                ValidIssuer = securityKeyProvider.Issuer
            }

        };
        app.UseJwtBearerAuthentication(jwtOptions);

    }

答案 1 :(得分:0)

对于希望通过JavaScript执行此操作的任何人,我都设法按照此博客中的步骤进行操作。您可以通过将令牌放在jwt.io

中来找到观众

https://blog.dirk-eisenberg.de/2014/08/30/validate-authentication_token-from-microsoft-liveid-with-node-express-jwt/

const validateLiveJWT = (token) => {
    const secret = '<<SECRET>>';
    const sha256 = crypto.createHash('sha256');
    sha256.update(secret + 'JWTSig', 'utf8');
    const secretBase64 = sha256.digest('base64');
    const secret = new Buffer(secretBase64, 'base64');

    const options = {
        audience: '<<AUDIENCE>>',
        issuer: 'urn:windows:liveid',
    };

    return new Promise((resolve) => {
        jwt.verify(token, secret, options, (err: any, claims: any) => {
            if (err) {
                resolve(undefined);
            } else {
                resolve(claims);
            }
        });
    });
}