简体   繁体   English

使用 Spring Boot 的 OAuth2 SSO 没有授权屏幕

[英]OAuth2 SSO with Spring Boot without the authorization screen

I have resource, authorization and _ui applications written using Spring Boot 1.5.3, OAuth2 and MongoDB.我有使用 Spring Boot 1.5.3、OAuth2 和 MongoDB 编写的资源、授权和 _ui 应用程序。

The resources are going to be accessed from mobile apps as well as a couple of web applications (one for regular users and the other one for admins).这些资源将从移动应用程序和几个 Web 应用程序(一个供普通用户使用,另一个供管理员使用)访问。 The apps are quite similar to the samples from the guides by Dave Syer.这些应用程序与 Dave Syer 的指南中的示例非常相似。 What different is that the users are stored in the database and the clients are stored in an xml file located in the resources folder of the authorization server.不同之处在于,用户存储在数据库中,而客户端存储在授权服务器资源文件夹中的 xml 文件中。

I am struggling with the logon experience for the web users.我正在为网络用户的登录体验而苦苦挣扎。 Following the guides for the JWT based OAuth app, after the login page, the user is redirected to the authorization screen, which is not the desired behavior.按照基于 JWT 的 OAuth 应用程序的指南,在登录页面之后,用户将被重定向到授权屏幕,这不是所需的行为。 Ie, I don't want my authorization server to ask if the user trusts my web application to access its resources .即,我不希望我的授权服务器询问用户是否信任我的 Web 应用程序来访问其资源 Instead, I want users redirected to the ui pages right after login, as one would expect.相反,我希望用户在登录后立即重定向到 ui 页面,正如人们所期望的那样。

I found this project on GitHub (very similar to the apps from the guide) which behaves exactly as I want, but once I start customizing it by adding my authentication and authorization implementation, it reverts back to using the authorization screen.在 GitHub 上找到了这个项目(与指南中的应用程序非常相似),它的行为完全符合我的要求,但是一旦我开始通过添加我的身份验证和授权实现对其进行自定义,它就会恢复使用授权屏幕。 Apparently, I am missing something, but I was not able to figure out what exactly.显然,我遗漏了一些东西,但我无法弄清楚到底是什么。

authorization/src/main/resourcs/application.yml授权/src/main/resources/application.yml

security:
  oauth2:
    client:
      client-id: trusted-app
      client-secret: secret
      scope: read, write
      auto-approve-scopes: .*
  authorization:
      check-token-access: permitAll()
server:
  port: 9999
  context-path: /uaa
mongo:
  db:
    name: myappname

authorization/src/main/resourcs/client-details.xml授权/src/main/resources/client-details.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:oauth="http://www.springframework.org/schema/security/oauth2"

   xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/security/oauth2
                    http://www.springframework.org/schema/security/spring-security-oauth2.xsd">

<oauth:client-details-service id="client-details-service">

    <!-- Web Application clients -->
    <oauth:client
            client-id="trusted-app"
            secret="secret"
            authorized-grant-types="authorization_code, password,refresh_token"
            authorities="ROLE_WEB, ROLE_TRUSTED_CLIENT"
            access-token-validity="${oauth.token.access.expiresInSeconds}"
            refresh-token-validity="${oauth.token.refresh.expiresInSeconds}"/>
    </oauth:client-details-service>
</beans>

authorization/src/main/java/AuthorizationApplication.java授权/src/main/java/AuthorizationApplication.java

@SpringBootApplication
@RestController
public class AuthorizationApplication extends AuthorizationServerConfigurerAdapter {

    @RequestMapping("/user")
    @ResponseBody
    public Principal user(Principal user) {
        return user;
    }

    @Configuration
    static class MvcConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("login").setViewName("login");
            registry.addViewController("/").setViewName("index");
        }
    }

    @Configuration
    @Order(-20)
    static class LoginConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .formLogin().loginPage("/login").permitAll()
            .and()
                .requestMatchers()
                .antMatchers("/", "/login", "/oauth/authorize", "/oauth/confirm_access")
            .and()
                .authorizeRequests()
                .anyRequest().authenticated();
        }
    }

    @Configuration
    @EnableAuthorizationServer
    @ImportResource({"classpath*:client-details.xml"})
    protected static class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private AuthenticationManager authenticationManager;

        @Resource(name="client-details-service")
        private ClientDetailsService clientDetailsService;

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.withClientDetails(clientDetailsService);
        }

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

        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            return converter;
        }
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new StandardPasswordEncoder();
    }

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

}

authorization/src/main/java/mypackage/UserService.java授权/src/main/java/mypackage/UserService.java

@Service
public class UserService implements UserDetailsService {

    private UserAccountRepository userAccountRepository;

    @Autowired
    public UserService(UserAccountRepository userAccountRepository){
        this.userAccountRepository = userAccountRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        UserAccount userAccount = userAccountRepository.findByEmail(s);

        if (userAccount != null) {
            return userAccount;
        } else {
            throw new UsernameNotFoundException("could not find the user '" + s + "'");
        }
   }
}

ui/src/main/resources/application.yml ui/src/main/resources/application.yml

auth-server: http://localhost:9999/uaa
server:
  port: 8080
spring:
  aop:
    proxy-target-class: true
security:
  oauth2:
    client:
      clientId: trusted-app
      clientSecret: secret
      access-token-uri: ${auth-server}/oauth/token
      user-authorization-uri: ${auth-server}/oauth/authorize
      scope: read, write
    resource:
      token-info-uri: ${auth-server}/oauth/check_token

ui/src/main/java/UiApplication.java ui/src/main/java/UiApplication.java

@SpringBootApplication
@EnableOAuth2Sso
public class UiApplication extends WebSecurityConfigurerAdapter{

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

    @Bean
    OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext, OAuth2ProtectedResourceDetails details) {
        return new OAuth2RestTemplate(details, oauth2ClientContext);
    }
}

From http://www.springframework.org/schema/security/spring-security-oauth2.xsd Element client-details-service > complexType client > attribute autoaprove来自http://www.springframework.org/schema/security/spring-security-oauth2.xsd Element client-details-service > complexType client > attribute autoaprove

Scopes or scope patterns that are autoapproved (comma-separated), or just "true" to autoapprove all.自动批准的范围或范围模式(以逗号分隔),或者只是“真”以自动批准所有。

Just add the autoapprove="true" attribute to your trusted-app in client-details.xml .只需将autoapprove="true"属性添加到client-details.xml中的 trusted-app。 That way the authserver will not request user's confirmation to access the resources.这样 authserver 将不会请求用户确认访问资源。

Here is an example of how to implement this behaviour directly in your Java configuration. 下面是一个示例,说明如何在 Java 配置中直接实现此行为。

Additionally, if your clients are provided by a database, actually DataSource , then the AUTOAPPROVE column of related client should be set to 'true' in the table OAUTH_CLIENT_DETAILS .此外,如果您的客户端由数据库提供,实际上是DataSource ,则相关客户端的AUTOAPPROVE列应在表OAUTH_CLIENT_DETAILS中设置为“true”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM