Spring Boot 2.5.3 OAuth2 - Auth-Server 和 Webservice 分开,登录后没有端点工作 [英] Spring Boot 2.5.3 OAuth2 - Auth-Server and Webservice separate, after Login no endpont works

查看:48
本文介绍了Spring Boot 2.5.3 OAuth2 - Auth-Server 和 Webservice 分开,登录后没有端点工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照 https://developer 上的示例.okta.com/blog/2019/03/12/oauth2-spring-security-guide 使用项目Create an OAuth 2.0 ServerBuild Your Client App 登录后,任何访问的端点都会跳转到根端点localhost:8082.

Following the example on https://developer.okta.com/blog/2019/03/12/oauth2-spring-security-guide using the projects Create an OAuth 2.0 Server and Build Your Client App after the login, any endpoint accessed jumps to the root endpoint localhost:8082.

我不使用 Thymeleaf,因为我的网络服务返回的是数据,而不是页面.

I don't use Thymeleaf, as my webservice returns data, not a page.

OAuth 2.0 服务器项目

OAuth 2.0 Server project

@SpringBootApplication
@EnableResourceServer
public class Demo2Application {
    public static void main(String[] args) {
        SpringApplication.run(Demo2Application.class, args);
    }
}

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    private final PasswordEncoder passwordEncoder;
    
    public AuthorizationServerConfig(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }    
    
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("abcd")
            .secret(passwordEncoder.encode("fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9"))
            .authorizedGrantTypes("authorization_code")
            .scopes("user_info")
            .autoApprove(true)
            .redirectUris("http://localhost:8082/login/oauth2/code/");
    }

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


@Configuration
@Order(1)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatchers()
            .antMatchers("/login", "/oauth/authorize")
            .and()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("john")
            .password(passwordEncoder().encode("doe"))
            .roles("USER");
    }
    
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }    
}

@RestController
public class UserController {
    @GetMapping("/user/me")
    public Principal user(Principal principal) {
        return principal;
    }    
}

application.properties
server.port=8090

pom.xml
<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.5.1.RELEASE</version>
</dependency>     
<dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
    <version>2.5.2</version>
</dependency>           
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

我省略了项目最初使用的上下文路径.

I omit the context path, which the project originally uses.

网络服务项目

@RestController
public class MyRESTController {

    @GetMapping("/securedPage")
    public String securedPage(Principal principal) {
        return "securedPage";
    }

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

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

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


application.properties
server.port=8082
server.servlet.session.cookie.name=UISESSION

spring.security.oauth2.client.registration.custom-client.client-id=abcd
spring.security.oauth2.client.registration.custom-client.client-secret=fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9
spring.security.oauth2.client.registration.custom-client.client-name=Auth Server
spring.security.oauth2.client.registration.custom-client.provider=custom-provider
spring.security.oauth2.client.registration.custom-client.scope=user_info
spring.security.oauth2.client.registration.custom-client.redirect-uri=http://localhost:8082/login/oauth2/code/
spring.security.oauth2.client.registration.custom-client.client-authentication-method=basic
spring.security.oauth2.client.registration.custom-client.authorization-grant-type=authorization_code

spring.security.oauth2.client.provider.custom-provider.authorization-uri=http://localhost:8090/oauth/authorize
spring.security.oauth2.client.provider.custom-provider.token-uri=http://localhost:8090/oauth/token
spring.security.oauth2.client.provider.custom-provider.user-info-uri=http://localhost:8090/user/me
spring.security.oauth2.client.provider.custom-provider.user-name-attribute=name

pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

效果很好.

现在,当我将 OAuth 2.0 Server 项目与我的 webservice 项目一起使用时,意味着我将演示 webservice 项目中的应用程序属性添加到我的 application.properties 我无法访问任何其他端点,但根端点 http://localhost:8082.

Now, when I use the OAuth 2.0 Server project with my webservice project, means I add the application properties from the demo webservice project into my application.properties I cannot access any other endpoints but the root endpoint http://localhost:8082.

我假设我的 webservice 项目中的 WebSecurityConfig 是造成这种情况的原因.它看起来像这样:

I assume that the WebSecurityConfig in my webservice project is the reason for that. It looks like this:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    public static final String ROLE_MYUSER = "MYUSER";
    public static final String ROLE_MYADMIN = "MYADMIN";
    
    private MyUserProperties myUserProperties;

    public WebSecurityConfig(MyUserProperties myUserProperties) {
        // Load usernames and passwords from properties file
        this.myUserProperties = myUserProperties;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            //.httpBasic()
            .and()
            .authorizeRequests()
                .antMatchers("/").permitAll()
            
                .antMatchers("/abc/**").hasRole(ROLE_MYUSER)
                .mvcMatchers(HttpMethod.GET, "/def1/{name}", "/def2/{name}").hasRole(ROLE_MYUSER)
                .mvcMatchers(HttpMethod.PATCH, "/def/{name}", "/def2/{name}").hasRole(ROLE_MYUSER)           
                .antMatchers("/ghi/**").hasRole(ROLE_MYUSER)
                //... and so on
            
                .antMatchers("/**").hasRole(ROLE_MYADMIN)
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .oauth2Login();    
            //.csrf().disable()
            //.formLogin().disable();
    }    

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        UserDetails myuser = User
            .withUsername(myUserProperties.getPortal().get("user"))
            .password("{noop}" + myUserProperties.getPortal().get("pass"))
            .roles(ROLE_MYUSER)
            .build();

        UserDetails myadmin = User
            .withUsername(myUserProperties.getAdmin().get("user"))
            .password("{noop}" + myUserProperties.getAdmin().get("pass"))
            .roles(ROLE_MYUSER, ROLE_MYADMIN)
            .build();

        InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();

        userDetailsManager.createUser(myuser);
        userDetailsManager.createUser(myadmin);

        return userDetailsManager;
    }   
}

我有 Basic Auth 到目前为止,我定义了我的两个用户在一个

I had Basic Auth so far, I defined my two users with the two roles in a

@Bean
@Override
public UserDetailsService userDetailsService() {

现在切换到我删除的 OAuth2

Now switching to OAuth2 I removed in

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

线条

.httpBasic()
.csrf().disable()
.formLogin().disable()

并添加

.oauth2Login()

Web 浏览器中的行为如下

The behavior in the web browser is the following

http://localhost:8082

从该根端点正确传递数据,无需任何登录.

delivers correctly the data from that root endpoint, without any login.

任何其他端点,例如

http://localhost:8082/abc

首先进入登录页面,在那里我从 OAuth 2.0 Server 项目中输入定义的用户 john/doe,之后它不显示来自端点 http 的预期数据://localhost:8082/abc ,但跳转回根端点 http://localhost:8082.

first leads to the login page, where I enter the defined user john / doe from the OAuth 2.0 Server project, after that it doesn't show the expected data from the endpoint http://localhost:8082/abc , but jumps back to the root endpoint http://localhost:8082.

我尝试的第一步是放置

@Bean
@Override
public UserDetailsService userDetailsService() {

在OAuth 2.0 Server项目中,进入类

in the OAuth 2.0 Server project, into the class

@Configuration
@Order(1)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

但是登录无效,它只接受john/doe.

but with that the login didn't work, it only accepted john / doe.

下一步是删除

@Bean
@Override
public UserDetailsService userDetailsService() {

也来自那个类并在

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

john/doe 的定义位置.

我的一个用户的登录现在可以工作了,但错误的行为仍然存在.还有哪些地方需要修改?

The login with one of my users works now, but the wrong behavior still remains. What else has to be altered, and where?

对我的 Web 服务项目中端点的访问权限取决于用户拥有的角色.

The access to the endpoints in my webservice project depends on the roles the user has.

我的pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency> 

推荐答案

这里的解决方案 OAuth2 客户端主体在通过其他自定义授权服务器 (SpringBoot2 & OAuth2) 进行身份验证时没有 GrantedAuthorities

解决了.

CustomOAuth2User 
CustomOAuth2UserService 
CustomAuthoritiesExtractor

这篇关于Spring Boot 2.5.3 OAuth2 - Auth-Server 和 Webservice 分开,登录后没有端点工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆