将特定请求重定向到登录页面,并在spring boot应用程序中为其他人抛出401

时间:2018-03-07 14:51:15

标签: java spring spring-boot oauth-2.0

我有一个Spring Boot应用程序,只有很少的休息端点。此应用程序还提供使用React开发的html页面和js文件。

我已使用spring oauth2为此应用程序实现了用户身份验证。当用户未经过身份验证时,请求将重定向到登录页面,或者是对html页面或REST端点的请求。但我不希望REST端点的请求将重定向响应返回到登录页面,而只返回401.

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:0)

您可以做的是定义这样的自定义身份验证入口点。

对于每个未经授权的请求,它们都将登陆您的自定义入口点。

在这里,您可以添加任何自定义逻辑,以仅检查您希望使用401回答的REST请求类型。

public class AjaxAwareLoginUrlAuthenticationEntryPoint extends
    LoginUrlAuthenticationEntryPoint {

    private static final RequestMatcher requestMatcher = new ELRequestMatcher(
            "hasHeader('X-Requested-With','XMLHttpRequest')");

    @SuppressWarnings("deprecation")
    public AjaxAwareLoginUrlAuthenticationEntryPoint() {
        super();
    }

    public AjaxAwareLoginUrlAuthenticationEntryPoint(String loginFormUrl) {
        super(loginFormUrl);
    }

    @Override
    public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException, ServletException {
        if(isPreflight(request)){
            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
        } else if (isRestRequest(request)) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
        } else {
            super.commence(request, response, authException);
        }
    }

    /**
   * Checks if this is a X-domain pre-flight request.
     * @param request
     * @return
     */
    private boolean isPreflight(HttpServletRequest request) {
        return "OPTIONS".equals(request.getMethod());
    }

    /**
     * Checks if it is a rest request
     * @param request
     * @return
     */
    protected boolean isRestRequest(HttpServletRequest request) {
        return requestMatcher.matches(request);
    }
}

然后添加适当的xml配置

<security:http disable-url-rewriting="true" use-expressions="true" 
    entry-point-ref="ajaxAwareLoginUrlAuthenticationEntryPoint"> 
    <security:form-login 
        authentication-failure-url="/login?error=1" 
        login-processing-url="/login/submit"/>
    <security:logout logout-url="/logout" logout-success-url="/login"/>
    <security:intercept-url pattern="/" access="permitAll" />
    <security:intercept-url pattern="/css/**" access="permitAll" />
    <security:intercept-url pattern="/images/**" access="permitAll" />
    <security:intercept-url pattern="/js/**" access="permitAll" />
    <security:intercept-url pattern="/login" access="permitAll" />
    <security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>

<bean id="ajaxAwareLoginUrlAuthenticationEntryPoint" class="com.bmchild.service.user.AjaxAwareLoginUrlAuthenticationEntryPoint">
    <constructor-arg value="/login" />
</bean>