RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 810931
Accepted
ЮрийСПб
ЮрийСПб
Asked:2020-04-07 22:06:34 +0000 UTC2020-04-07 22:06:34 +0000 UTC 2020-04-07 22:06:34 +0000 UTC

能够在 spring 和 access_token 中以及通过浏览器中的登录表单授权请求

  • 772

鉴于:

spring+上的项目kotlin。实现了access_token通过数据库并使用它访问资源。

一个任务:

为通过浏览器中的登录表单登录的用户实现访问资源的能力。

问题:

只有一种授权方法有效。如果添加注释@EnableResourceServer,则带有令牌的访问方法有效。在浏览器中请求任何页面时,它只会显示“未经授权”错误,包括。在地址/login。如果您/login使用附加的令牌登录,它将显示404. 如果注释@EnableResourceServer被删除,则可以通过浏览器中的登录表单访问并获取令牌,但所有带有令牌的请求都将重定向到/login,即 令牌不被接受。

问题:

如何让它发挥作用?

从理论上讲,您需要在这里写一些东西,但是几个小时的谷歌搜索并没有让您了解到底是什么:

@Configuration
@EnableWebSecurity
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
class WebSecurityConfiguration : WebSecurityConfigurerAdapter() {

    @Bean
    fun passwordEncoder() = BCryptPasswordEncoder()

    @Bean
    fun authenticationProvider(): DaoAuthenticationProvider {
        val authenticationProvider = DaoAuthenticationProvider()
        authenticationProvider.setUserDetailsService(userDetailsService)
        authenticationProvider.setPasswordEncoder(passwordEncoder())
        return authenticationProvider
    }

    @Bean
    override fun authenticationManagerBean(): AuthenticationManager {
        return super.authenticationManagerBean()
    }

    @Autowired
    lateinit var userDetailsService: UserServiceImpl

    @Autowired
    fun configureGlobal(auth: AuthenticationManagerBuilder) {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder())
                .and()
                .authenticationProvider(authenticationProvider())
    }

    override fun configure(http: HttpSecurity) {
        http
                .csrf().disable()
        http
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin().permitAll()
    }
}

附加信息:

链接到整个项目GitHub:https ://github.com/mohaxspb/springSecurityExample/tree/v0.0.1

要开始工作,您需要在带有密码postgresql的用户名下安装并创建一个名称的数据库- 然后,在启动时,将在数据库中创建一个包含用户的表,并在那里添加一个用户,您可以在该表下可以使用登录名和密码登录。要获取令牌,您需要指定client_id :和client_secret : (该数据也在服务器启动时写入数据库)postgrestesttestspringbootdbtest@test.rupasswordclient_idclient_secret

java
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    ЮрийСПб
    2020-04-13T05:43:59Z2020-04-13T05:43:59Z

    问题解决了。它包括以下事实:当@EnableResourceServer为每个请求向过滤器链添加注释时,添加了 a OAuth2AuthenticationProcessingFilter,在默认情况下,Cookie通过登录表单进入时使用的帮助明确禁止身份验证的设置是启用。

    另一方面,如果注释被删除@EnableResourceServer,那么过滤器OAuth2AuthenticationProcessingFilter将不会被添加,并且 spring 将不知道有必要通过尝试使用令牌进行身份验证来响应带有令牌的请求。

    最后,我这样做了:

    1. 删除了注释@EnableResourceServer。

    2. 为每个请求手动添加OAuth2AuthenticationProcessingFilter到过滤器链中,向它指示可以使用身份验证跳过请求Cookie

    3. 此过滤器设置AuthenticationManager类型OAuth2AuthenticationManager

    4. OAuth2AuthenticationManager是一个附加的AuthenticationManager,它传递了一个实现ClientDetailsService(负责提供有关客户端应用程序的数据以进行授权)和一个ResourceServerTokenServices变成具有类型access_token的对象的实现AuthenticationOAuth2Authentication

    5. 因为 spring需要知道哪个是AuthenticationManager主要的,需要用注解标记默认@Primary

    因此,当 spring 在请求中没有找到 cookie 或 token 时,它会重定向到登录页面。输入数据后,它会在浏览器中设置一个 cookie 并使用它验证请求。如果请求中有令牌,则触发添加的过滤器并尝试使用令牌对请求进行身份验证。如果成功,将身份验证设置为SecurityContext。

    结果,实现WebSecurityConfigurerAdapter如下所示:

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
    class WebSecurityConfiguration : WebSecurityConfigurerAdapter() {
    
        @Autowired
        lateinit var clientDetailsService: ClientServiceImpl
    
        @Bean
        fun tokenServices() = AccessTokenServices()
    
        @Bean
        fun passwordEncoder() = BCryptPasswordEncoder()
    
        @Bean
        fun authenticationProvider(): DaoAuthenticationProvider {
            val authenticationProvider = DaoAuthenticationProvider()
            authenticationProvider.setUserDetailsService(userDetailsService)
            authenticationProvider.setPasswordEncoder(passwordEncoder())
    
            return authenticationProvider
        }
    
        @Primary
        @Bean
        override fun authenticationManagerBean(): AuthenticationManager {
            return super.authenticationManagerBean()
        }
    
        @Autowired
        lateinit var userDetailsService: UserServiceImpl
    
        @Autowired
        fun configureGlobal(auth: AuthenticationManagerBuilder) {
            auth
                    .authenticationProvider(authenticationProvider())
                    .userDetailsService(userDetailsService)
                    .passwordEncoder(passwordEncoder())
        }
    
        @Bean
        fun oauth2authenticationManager(): OAuth2AuthenticationManager {
            val authManager = OAuth2AuthenticationManager()
            authManager.setClientDetailsService(clientDetailsService)
            authManager.setTokenServices(tokenServices())
    
            return authManager
        }
    
        @Bean
        fun myOAuth2Filter(): Filter {
            val filter = OAuth2AuthenticationProcessingFilter()
            filter.setAuthenticationManager(oauth2authenticationManager())
            //allow auth with cookies (not only with token)
            filter.setStateless(false)
    
            return filter
        }
    
        override fun configure(http: HttpSecurity) {
            http
                    .csrf()
                    .disable()
            http
                    .authorizeRequests()
                    .anyRequest()
                    .authenticated()
            http
                    .formLogin()
                    .permitAll()
    
            http
                    .addFilterBefore(
                            myOAuth2Filter(),
                            BasicAuthenticationFilter::class.java
                    )
        }
    }
    

    v0.03 标签下仓库中的所有代码


    您可以通过正确实现ResourceServerConfigurerAdapter和返回来缩短代码@EnableResourceServer。如果它有效,我会更新答案。

    • 7

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5