自定义身份验证提供程序不会被称为Spring Security

时间:2015-02-28 22:24:16

标签: java authentication spring-security

我正在尝试实现自定义AuthenticationProvider来验证对所有受保护URL的调用。我已经实现了所有方法并且认为我的xml配置是正确的,但是对受保护URL的调用总是转到entry-point-ref类(我抛出401错误)。这是跳过我的身份验证提供程序(我的身份验证方法中有日志语句,并且知道它没有被调用)。从其他帖子我了解到支持方法可能是罪魁祸首,但我已将其设置为始终返回true,因此这不应该是我的问题。

我的安全上下文代码:

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

    <security:http 
            use-expressions="true"
            auto-config="false"
            create-session="stateless"
            entry-point-ref="unauthorizedEntryPoint"
            authentication-manager-ref="authenticationManager">
        <security:intercept-url pattern="/User/sign_up/*" access="permitAll" />
        <security:intercept-url pattern="/User/authenticate/**" access="permitAll" />
        <security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
    </security:http>

    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="customAuthenticationProvider" />
    </authentication-manager>

    <beans:bean id="customAuthenticationProvider" class="pathto:CustomAuthenticationProvider" />

    <beans:bean id="unauthorizedEntryPoint" class="pathto:UnauthorizedEntryPoint" /

web.xml代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/security-context.xml
        </param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

UnauthorizedEntryPoint:

public class UnauthorizedEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException authenticationException) throws IOException, ServletException {
        System.out.println("in unauth");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failure: UnauthorizedEntryPoint Token invalid");
    }

}

AuthenticationProvider :(目前未在此处进行任何身份验证)

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication auth)
            throws AuthenticationException {
        System.out.println("in authenticate");
        String username = auth.getName();
        String password = auth.getCredentials().toString();
        List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();
        System.out.println("username: "+username+". password: "+ password);
        if (true) { //checkPassword(password, user.getPasswords())) {
            AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
            return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(), AUTHORITIES);
        }
        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }

更新: 我正在使用参数j_username和j_password使用Advanced Rest Client对此进行测试。这是正确的还是问题?

您对可能出现的问题有什么了解吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

为什么不删除authentication-manager-ref下的security:http?您已经声明了authentication-manager代码。

<security:http 
        use-expressions="true"
        auto-config="false"
        create-session="stateless"
        entry-point-ref="unauthorizedEntryPoint">
    <security:intercept-url pattern="/User/sign_up/**" access="permitAll" />
    <security:intercept-url pattern="/User/authenticate/**" access="permitAll" />
    <security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
</security:http>

除了;不是你问题的一部分,而只是建议:

@Override
public boolean supports(Class<?> authentication) {
    return authentication.equals(UsernamePasswordAuthenticationToken.class);
}

答案 1 :(得分:0)

您没有配置Web身份验证机制,因此无需调用身份验证管理器。因此,请求始终会到达您的身份验证入口点(对未经身份验证的用户调用),并且您会收到您观察到的错误。通常,身份验证入口点会执行重定向到登录表单或发送WWW-Authenticate标头的操作。

您需要配置表单或基本身份验证之类的内容(请参阅手册或项目附带的示例)。请注意,您还将应用程序配置为无状态,因此需要对每个请求进行身份验证。

相关问题