Spring oauth2 AuthorizationServer 不重定向

Posted

技术标签:

【中文标题】Spring oauth2 AuthorizationServer 不重定向【英文标题】:Spring oauth2 AuthorizationServer doesn't redirect 【发布时间】:2020-06-03 15:13:28 【问题描述】:

我使用 Spring Security 和 Oauth2 设置了授权服务。 一切正常,直到我尝试自定义登录页面。 如果我在我的自定义登录页面登录,它会重定向回登录页面,而不是回调 url。

GET /login -> POST /login -> GET /login

SecurityConfig.java


@Configuration
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 
    @Autowired
    DataSource dataSource;

  

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

    @Override
    protected void configure(AuthenticationManagerBuilder
                                     auth) throws Exception 
        auth.parentAuthenticationManager(authenticationManagerBean())
                .jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("select mail,password,enabled "
                        + "from users "
                        + "where mail = ?")
                .authoritiesByUsernameQuery("select mail,authority "
                        + "from users "
                        + "where mail = ?");
    


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

    @Bean
    public BCryptPasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    



AuthorizationServerConfig.java

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private DataSource dataSource;


    @Override
    public void configure(final AuthorizationServerSecurityConfigurer
                                  oauthServer) 
        oauthServer.tokenKeyAccess("permitAll()")
                .checkTokenAccess("permitAll()");
    

    @Override
    public void configure(final ClientDetailsServiceConfigurer
                                  clients) throws Exception 
        clients
                .jdbc(dataSource);

  
    

    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer
                                  endpoints) throws Exception 
        endpoints
                .tokenStore(tokenStore())
                .accessTokenConverter(accessTokenConverter())
                .authenticationManager(authenticationManager);
    

    @Bean
    public TokenStore tokenStore() 
        //return new JdbcTokenStore(dataSource);
        return new JwtTokenStore(accessTokenConverter());
    

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() 
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("dein-signing-key");
        return converter;
    

login.html

  <form  action="/login" method="POST">
            <div class="column">
                <div class="title">Anmelden</div>

                <div th:if="$param.error" class="alert alert-error">
                    Invalid username and password.
                </div>
                <div th:if="$param.logout" class="alert alert-success">
                    You have been logged out.
                </div>

                <input id="username" name="username" type="email" class="login input" placeholder="E-Mail Adresse"/>

                <input id="password" name="password" type="password" class="login input" placeholder="Passwort"/>
                <br>
                <p style="text-align: center; margin-top: 20px;"><a href="/password-forgotten">Passwort vergessen?</a></p>

                <button  style=" margin-top: 20px; margin-bottom: 20px" type="submit" class="button cancel login">Anmelden</button>
            </div>
        </form>

【问题讨论】:

你发送 CSRF 令牌吗? 那是个错误。我忘记了令牌!谢谢@dur 【参考方案1】:

您必须将 CSRF 令牌与您的自定义登录页面一起发送,请参阅Spring Security Reference:

9.21.1 表单登录Java配置

[...]

下面是我们当前配置使用 JSP 实现的示例登录页面:

[...]

<c:url value="/login" var="loginUrl"/>
<form action="$loginUrl" method="post">       1
    <c:if test="$param.error != null">        2
        <p>
            Invalid username and password.
        </p>
    </c:if>
    <c:if test="$param.logout != null">       3
        <p>
            You have been logged out.
        </p>
    </c:if>
    <p>
        <label for="username">Username</label>
        <input type="text" id="username" name="username"/>  4
    </p>
    <p>
        <label for="password">Password</label>
        <input type="password" id="password" name="password"/>  5
    </p>
    <input type="hidden"                        6
        name="$_csrf.parameterName"
        value="$_csrf.token"/>
    <button type="submit" class="btn">Log in</button>
</form>

1 - 对/login URL 的 POST 将尝试对用户进行身份验证

2 - 如果查询参数error 存在,则尝试进行身份验证并失败

3 - 如果查询参数logout存在,则用户成功登出

4 - 用户名必须以 HTTP 参数的形式出现,名为 username

5 - 密码必须以 HTTP 参数的形式出现,名为 password

6 - 我们必须在“包含 CSRF 令牌”部分了解更多信息,请阅读参考资料的第 5.1.1 节“跨站请求伪造 (CSRF)”部分

【讨论】:

以上是关于Spring oauth2 AuthorizationServer 不重定向的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Security OAuth2 设置 - 无法找到 oauth2 命名空间处理程序

Spring Security---Oauth2详解

Spring OAuth2.0 - 动态注册 OAuth2.0 客户端

Spring安全中的Oauth2客户端

Spring Cloud Oauth2 初探

OAuth2 Spring Security - OAuth2AuthenticationProcessingFilter 不起作用