我正在使用Azure AD进行Spring Boot应用程序的用户身份验证。 由于某些原因,我需要从spring引导代码生成令牌并返回它。到目前为止,这是我所达到的。
1个Azure广告配置。
我已经在azure广告中配置了一个应用,并且我注册了一个用户和一个组。
在应用程序中,我也创建了一个秘密
现在在我的春季启动应用程序中,我添加了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
使用此令牌,我可以完美地传递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令牌。
我收到的令牌如下:
如您所见,令牌具有与我的用户相关的信息,依此类推,这似乎是正确的,但是签名无效,并且是否使用此令牌向我的应用发送了请求。显然,它给了我错误签名的错误。
我做错了什么?
非常感谢您
答案 0 :(得分:1)
您的令牌是正确的。它只是图API的特定标记。您将在 Jwt.Header 中看到一个nonce
。这意味着您需要特殊处理。正常处理将失败。
更新:
访问令牌是仅用于资源的不透明文本斑点。 如果您是获得Graph令牌的客户,请假设它是一个 永远不要看的加密字符串-有时会这样。 我们为Graph使用一种特殊的令牌格式,他们知道如何验证 -如果访问令牌不适合您,则不应查看。
参考:
答案 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