手动验证Azure AD Graph API访问令牌

参考链接

using Bestrane.OPS.Core;
using IdentityModel;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace Bestrane.OPS.API.Attributes
{
    public class JwtAuthenticationAttribute : AuthorizationFilterAttribute
    {
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            if (!IsAuthorized(actionContext))
            {
                HandleUnauthorizedRequest(actionContext);
            }
        }

        private bool IsAuthorized(HttpActionContext actionContext)
        {
            // Get the Authorization header from the request
            var authHeader = actionContext.Request.Headers.Authorization;
            if (authHeader != null && authHeader.Scheme.Equals("Bearer", StringComparison.OrdinalIgnoreCase))
            {
                try
                {
                    var policyNames = new List<string> { "eta", "pod", "routeplanner" };
                    var accessToken = authHeader.Parameter;

                    string rootDirectory = AppContext.BaseDirectory;
                    var configReader = new JsonConfigReader($"{rootDirectory}/AzureConfig.json");
                    var clientId = configReader.GetValueByNodePath<string>("AzureAd/ClientId");
                    var tenantId = configReader.GetValueByNodePath<string>("AzureAd/TenantId");

                    var openIdConfigurationEndpoint = $"https://login.microsoftonline.com/{tenantId}/v2.0/.well-known/openid-configuration";
                    IConfigurationManager<OpenIdConnectConfiguration> configurationManager = 
                        new ConfigurationManager<OpenIdConnectConfiguration>(openIdConfigurationEndpoint, 
                        new OpenIdConnectConfigurationRetriever(), 
                        new HttpDocumentRetriever());
                    OpenIdConnectConfiguration openIdConfig =  configurationManager.GetConfigurationAsync(CancellationToken.None).Result;
                    var keys = openIdConfig.SigningKeys.Where(x => x.GetType() == typeof(Microsoft.IdentityModel.Tokens.X509SecurityKey)).ToList();
                    TokenValidationParameters validationParameters = new TokenValidationParameters
                    {
                        ValidateAudience = false,
                        ValidateIssuer = false,
                        IssuerSigningKeys = keys,
                        ValidateLifetime = false,
                        ValidateIssuerSigningKey = false,
                        TokenReader = (string token1, TokenValidationParameters parameters) =>
                        {
                            string[] parts = token1.Split('.');
                            string header = parts[0];
                            string payload = parts[1];
                            string signature = parts[2];
                            var tokenHandler = new JwtSecurityTokenHandler();
                            var jsonToken = tokenHandler.ReadJwtToken(token1);
                            if (jsonToken.Header.TryGetValue("nonce", out object nonceAsObject))
                            {
                                string plainNonce = nonceAsObject.ToString();
                                using (SHA256 sha256 = SHA256.Create())
                                {
                                    byte[] hashedNonceAsBytes = sha256.ComputeHash(
                                        System.Text.Encoding.UTF8.GetBytes(plainNonce));
                                    string hashedNonce = Base64Url.Encode(hashedNonceAsBytes);
                                    jsonToken.Header.Remove("nonce");
                                    jsonToken.Header.Add("nonce", hashedNonce);
                                    header = tokenHandler.WriteToken(jsonToken).Split('.')[0];
                                    jsonToken = tokenHandler.ReadJwtToken($"{header}.{payload}.{signature}");
                                }
                            }
                            return jsonToken;
                        }
                    };
                    IdentityModelEventSource.ShowPII = true;
                    var handler = new JwtSecurityTokenHandler();
                    var principal = handler.ValidateToken(accessToken, validationParameters, out var token);
                    return principal != null;
                }
                catch (Exception ex)
                {
                    return false;
                }
            }
            return false;
        }

        private void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            // Return 401 Unauthorized response
            actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
        }

        private SecurityKey[] GetSigningKeys(string domain)
        {
            var jwksUrl = $"https://{domain}/.well-known/jwks.json";
            var jwksJson = new WebClient().DownloadString(jwksUrl);
            var jwks = new JsonWebKeySet(jwksJson);

            return jwks.Keys.ToArray();
        }
    }
}





这样就可以在用户访问每一个后台API的时候根据AccsessToken鉴权了

    public class OrderStatusController : BaseController
    {
        [JwtAuthentication]
        [HttpPost, Route("api/eta")]
        public async Task<IHttpActionResult> EstimatedTimeToArrival([FromBody] ETARequest request)
        {
              ......
              

               

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
哦,我理解错了你的问题。Azure Active Directory是微软提供的一种身份验证和授权服务,可以用于管理组织内的用户和应用程序。如果你想在Java应用程序中使用Azure AD进行身份验证,你可以使用Azure AD提供的Java SDK来完成。具体来说,你需要完成以下步骤: 1. 在Azure门户中创建一个Azure AD应用程序,并记录下应用程序的客户端ID和客户端机密。 2. 在Java应用程序中添加Azure AD Java SDK的依赖项,并使用客户端ID和客户端机密来初始化一个身份验证对象。 3. 使用身份验证对象来获取访问令牌,并将令牌用于调用Azure AD保护的API。 下面是一个使用Azure AD Java SDK进行身份验证的示例代码: ``` import com.microsoft.aad.msal4j.*; public class AzureADAuthExample { public static void main(String[] args) throws Exception { String clientId = "<your-client-id>"; String clientSecret = "<your-client-secret>"; String authority = "https://login.microsoftonline.com/<your-tenant-id>/"; IConfidentialClientApplication app = ConfidentialClientApplication.builder(clientId, ClientCredentialFactory.createFromSecret(clientSecret)) .authority(authority) .build(); ClientCredentialParameters parameters = ClientCredentialParameters.builder(Collections.singleton("<your-scope>")).build(); IAuthenticationResult result = app.acquireToken(parameters).get(); // Use the access token to call Azure AD protected API // ... } } ``` 在这个示例中,你需要将`<your-client-id>`、`<your-client-secret>`、`<your-tenant-id>`和`<your-scope>`替换为你自己的值。`<your-scope>`表示你要访问API的范围。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值