天蓝色的AD Spring Boot令牌生成无效签名

时间:2020-03-23 19:03:27

标签: java spring-boot authentication azure-active-directory token

我正在使用Azure AD进行Spring Boot应用程序的用户身份验证。 由于某些原因,我需要从spring引导代码生成令牌并返回它。到目前为止,这是我所达到的。

1个Azure广告配置。 我已经在azure广告中配置了一个应用,并且我注册了一个用户和一个组。 enter image description here -b enter image description here

在应用程序中,我也创建了一个秘密

现在在我的春季启动应用程序中,我添加了JWT筛选器和一些配置(我将不解释完整的配置,因为这将需要一段时间)

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Profile("AzureAdSecurized")
public class AzureSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private RestAuthenticationExceptionHandler restAuthenticationExceptionHandler;

    @Autowired
    private AADAppRoleStatelessAuthenticationFilter aadAuthenticationFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable().sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS );
        http.headers().frameOptions().disable();

        http.addFilterAfter(aadAuthenticationFilter, UsernamePasswordAuthenticationFilter.class );

        http.addFilterBefore( new CorsFilter(), ChannelProcessingFilter.class );

        http.exceptionHandling().authenticationEntryPoint( restAuthenticationExceptionHandler );

        //Configuracion Endpoints
        http.authorizeRequests().antMatchers( "/auth/login**" ).permitAll()
            .antMatchers( "/v2/api-docs", "/configuration/**", "/swagger*/**", "/webjars/**" ).permitAll()
            .antMatchers( "/actuator/**" ).permitAll().anyRequest().authenticated();
    }

我还添加了以下属性:

azure:
  activedirectory:
    tenant-id: 7XXXXX
    client-id: 5XXXXX
    session-stateless: true

spring:
  security:
    oauth2:
      client:
        registration:
          azure:
            client-id: 5XXX
            client-secret: dXXXX

如果我转到Microsoft的以下URL: https://login.microsoftonline.com/ / oauth2 / authorize?client_id =&response_type = id_token&redirect_uri = http%3A%2F%2Flocalhost%3A8080%2Flogin&nonce = 7362CAEA-9CA5–4B43–9BA3–34D7C303EBA7

我在重定向中获得了完美的令牌,例如:http://localhost:8080/login#id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IllNRUxIVDBndmIwbXhvU0RvWWZvbWp

enter image description here

使用此令牌,我可以完美地传递spring boot安全性的aadAuthenticationFilter。

重点是我必须从应用程序生成此令牌。

在我的春季启动应用中,我要添加: 我已按照教程进行操作,但是没有记住的URL地址

@RestController
@RequestMapping(LoginPaths.AUTH)
@Profile("AzureAdSecurized")
public class AADLoginController {

    private static final Logger LOG = LoggerFactory.getLogger( AADLoginController.class );

    @RequestMapping(value = LoginPaths.LOGIN, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public String generateTokenAzureAD() throws MalformedURLException, ExecutionException, InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool( 1 );
        AuthenticationContext context = new AuthenticationContext(
            "https://login.microsoftonline.com/<My-tenant>/oauth2/v2.0/authorize", false,
            service );
        Future<AuthenticationResult> future = context
            .acquireToken( "https://graph.microsoft.com",
                "<app-id>", "<username>",
                "<pass>", null );
        AuthenticationResult result = future.get();
        LOG.info( "Access Token - " + result.getAccessToken() );
        LOG.info( "Refresh Token - " + result.getRefreshToken() );
        LOG.info( "ID Token - " + result.getIdToken() );
        return "Bearer " + result.getAccessToken();
    }
}

通过使用库“ com.microsoft.aad.adal4j”类传递用户名和密码,我试图生成I令牌。

我收到的令牌如下:

如您所见,令牌具有与我的用户相关的信息,依此类推,这似乎是正确的,但是签名无效,并且是否使用此令牌向我的应用发送了请求。显然,它给了我错误签名的错误。

enter image description here

我做错了什么?

非常感谢您

2 个答案:

答案 0 :(得分:1)

您的令牌是正确的。它只是图API的特定标记。您将在 Jwt.Header 中看到一个nonce。这意味着您需要特殊处理。正常处理将失败。

更新

访问令牌是仅用于资源的不透明文本斑点。 如果您是获得Graph令牌的客户,请假设它是一个 永远不要看的加密字符串-有时会这样。 我们为Graph使用一种特殊的令牌格式,他们知道如何验证 -如果访问令牌不适合您,则不应查看。

参考:

https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/609#issuecomment-529537264

答案 1 :(得分:0)

我正在使用依赖项:

<dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>msal4j</artifactId>
        </dependency>

并以这种方式生成令牌:

public TokenDTO generateTokenAzureAD(CredentialsDTO credentialsDTO) {

        LoginValidator.validateLoginRequest( credentialsDTO );

        PublicClientApplication app;
        String AUTHORITY = authorityUrl + addTenantId;
        try {
            app = PublicClientApplication.builder( addAppId ).authority( AUTHORITY ).build();
        } catch (MalformedURLException e) {
            throw new MyException( ErrorCodes.ERROR_ADD_AUTHORITY_URL_NOT_VALID );
        }

        Set<String> scopes = Collections.singleton( addAppId + addAppScope );
        UserNamePasswordParameters parameters = UserNamePasswordParameters
            .builder( scopes, credentialsDTO.getUsername(), credentialsDTO.getPassword().toCharArray() ).build();

        Future<IAuthenticationResult> result = app.acquireToken( parameters );
        IAuthenticationResult auth;
        try {
            auth = result.get();
        } catch (InterruptedException | ExecutionException e) {
            throw new MyException( ErrorCodes.ERROR_ADD_AUTHORITY_URL_NOT_VALID );
        }

        return TokenUtils.fromAddAuthToTokenDTO( auth );
    }

哪里

authorityUrl = https://login.microsoftonline.com/

addTenantId = azureID租户

addAppId = azureID应用ID

addAppScope = /User.Read

对于作用域,您可以在Azure AD应用程序菜单的“暴露API”选项中创建一个新的对象

也感谢@TonyJu