如何在无状态微服务中使用 Spring Boot oAuth2 + Azure AD?

Don*_*mmy 8 spring spring-security azure spring-boot spring-security-oauth2

当我尝试使用Microsoft Azure的示例代码使用 oAuth2 和 Spring Boot 时,它使用有状态会话来检查身份验证/授权。你可以看到这一点:

  1. 它永远不会在任何调用中传递任何标头/JWT
  2. 它有一个 cookie“JSESSIONID”,您可以在新的邮递员会话中使用它(在不同的浏览器中获取它后),它会认为您已登录

这将不起作用,因为我们的微服务将是多个实例。

我如何将其转换为使用 JWT ( Authorization: Bearer AQab...) 而不是 cookie 进行后续调用?

依赖项:

//All using Spring Boot 2.0.5.RELEASE
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-webflux')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.security:spring-security-oauth2-client')
compile('org.springframework.security:spring-security-oauth2-jose')

//Using 2.0.7
compile('com.microsoft.azure:azure-active-directory-spring-boot-starter')
Run Code Online (Sandbox Code Playgroud)

配置:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;

@EnableWebSecurity
@EnableGlobalMethodSecurity( prePostEnabled = true )
public class OAuthConfig extends WebSecurityConfigurerAdapter
{
    @Autowired
    private OAuth2UserService<OidcUserRequest, OidcUser> userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .oauth2Login()
            .userInfoEndpoint()
            .oidcUserService( userService );
    }
}
Run Code Online (Sandbox Code Playgroud)

控制器:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MainController
{
    private OAuth2AuthorizedClientService clientService;

    @Autowired
    public MainController(OAuth2AuthorizedClientService clientService)
    {
        this.clientService = clientService;
    }

    @GetMapping( "checkrole" )
    @ResponseBody
    @PreAuthorize( "hasRole('ROLE__Test')" )
    public String group1()
    {
        return "ok";
    }

    @GetMapping( "/" )
    @ResponseBody
    public String getUser(OAuth2AuthenticationToken userToken)
    {
        //Printing out the oAuth token just for testing
        return clientService.loadAuthorizedClient(
            userToken.getAuthorizedClientRegistrationId(),
            userToken.getName()
        ).getAccessToken().getTokenValue();
    }
}
Run Code Online (Sandbox Code Playgroud)

应用程序.yml:

spring:
  security:
    oauth2:
      client:
        registration:
          azure:
            client-id: ${YOUR_CLIENT_ID:}
            client-secret: ${YOUR_CLIENT_SECRET:}

azure:
  activedirectory:
    tenant-id: ${YOUR_TENANT_OR_DIRECTORY_ID:}
    active-directory-groups: Test
Run Code Online (Sandbox Code Playgroud)

完整的示例代码

https://github.com/Microsoft/azure-spring-boot/tree/master/azure-spring-boot-samples/azure-active-directory-spring-boot-backend-sample