java - Spring Security - 实现 oauth2 sso

标签 java spring-security oauth-2.0 single-sign-on spring-security-oauth2

我想用 spring security 和 oauth2 sso 实现中央认证系统。换句话说,我有一个负责授权的 spring boot 应用程序和一个简单的客户端。我的客户有休息 API。首先,我从授权服务器获取 token ,然后向客户端 API 发送请求,其中授权 header 包含来自上述请求的不记名 token 。但是这个请求总是让我服务器登录页面

这里是服务端和客户端的实现:

Server

AuthorizationServerConfig.java

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

@Autowired
private AuthenticationManager authenticationManager;


@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer
            .tokenKeyAccess("permitAll()")
            .checkTokenAccess("isAuthenticated()");
}



@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory()
            .withClient("SampleClientId")
            .secret("{noop}secret")
            .authorizedGrantTypes("password")
            .scopes("user_info")
            .autoApprove(true);
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.authenticationManager(this.authenticationManager);
}

应用配置:

@SpringBootApplication
@EnableResourceServer
public class ApplicationConfig extends SpringBootServletInitializer {

public static void main(String[] args) {
    SpringApplication.run(ApplicationConfig.class, args);
}

}

安全配置:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //this is just example
    auth.inMemoryAuthentication().withUser("user").password("{noop}1234").roles("user");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.requestMatchers()
            .antMatchers("/login", "/oauth/authorize", "/oauth/token")
            .and()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll();

}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

application.yml:

server:
  port: 8900
  servlet:
    context-path: /auth

Client:

应用配置:

@SpringBootApplication
public class ApplicationConfig {

public static void main(String[] args) {
    SpringApplication.run(ApplicationConfig.class, args);
}

}

安全配置:

@Configuration
@EnableOAuth2Sso
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/", "/login**")
            .permitAll()
            .anyRequest()
            .authenticated();
}
}

测试 Controller :

@RestController
public class HomeController {

@GetMapping("/")
public String index() {
    return "home";
}

@RequestMapping("/admin")
public String admin() {
    return "admin";
}
}

application.yml:

server:
  port: 9000
  servlet:
    context-path: /client1
security:
  basic:
    enabled: false
  oauth2:
    client:
      clientId: SampleClientId
      clientSecret: secret
      accessTokenUri: http://localhost:8900/auth/oauth/token
      userAuthorizationUri: http://localhost:8900/auth/oauth/authorize
    resource:
      userInfoUri: http://localhost:8900/auth/user/me

首先,我将 client_id 和密码与用户名、密码和 grant_type 一起发送到 localhost:8900/auth/oauth/token 并得到如下结果:

{
  "access_token": "603b505f-e701-43d0-b8b8-976a2178f7ea",
  "token_type": "bearer",
  "expires_in": 43199,
  "scope": "user_info"
}

现在,我获取上面的 token 并向 localhost:9000/client1/admin 发送请求 header 包含上述标记。但客户端应用程序似乎忽略了标题并显示服务器登录页面作为结果。我该如何解决这个问题?

最佳答案

@EnableOAuth2Sso 是使用 OAuth 2.0 作为最终用户身份验证机制的注释(例如“A Login with Google”按钮)。此注释将您的应用连接到重定向到授权服务器上的登录页面,您将在该页面上登录,然后重定向回您的应用。

如果这是您的意图,那么您需要 update your Authorization Server to support the authorization_code grant flow而不是 password 授权流程。

但是,如果您的客户端严格来说是 REST API,那么您更有可能需要使用 @EnableResourceServer 而不是 @EnableOAuth2Sso 连接客户端。 A Resource Server是通过 Authorization HTTP header 将 token 作为授权的。

关于java - Spring Security - 实现 oauth2 sso,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53506622/

相关文章:

java - Java 需要学生成绩排序帮助

spring-security - Spring Security 身份验证入口点

java - Spring Security 3.0 Google Apps 使用 OpenID4Java 打开 id 登录

php - 将 angularjs webapp 连接到 REST API (PHP)

java - 这个奇怪的图标在 Intellij 上意味着什么?

java - 整个项目的语法突出显示已损坏

java - 为什么 thread.stop() 不起作用?

spring - Spring Security LDAP VS CAS VS OpenID 的区别

node.js - NodeJS 加密 RS-SHA256 和 JWT 承载

google-api - 无法刷新访问 token : response is "unauthorized_client"