Spring安全性 - 自定义令牌认证始终调用成功的处理程序

时间:2014-07-14 09:15:58

标签: java spring security authentication spring-security

我要实现自定义令牌身份验证。令牌来自请求参数或会话。

身份验证和授权方案如下所述:

  • 如果最终用户输入url:localhost:8080 / security / test?token = abc
  • 我们将从url获取令牌,根据令牌进行身份验证。
  • 如果令牌==' abc'然后返回真实认证;转到成功的处理程序,否则:返回false - 验证失败;去失败处理程序。

我有两大问题:

  • 即使我输入/ security / test?token = abc;过滤器扫描抛出所有映射(test / test1,test / test2,test / test3等等)
    • 即使我输入了令牌参数的任何值(例如:123),过滤器总是跳转到成功的处理程序,永远不会调用失败处理程序。

以下是我的实施

CustomAuthenticationFilter

public class CustomAuthenticationFilter extends AbstractAuthenticationProcessingFilter{

protected final Log logger = LogFactory.getLog(this.getClass());

private static final String SECURITY_TOKEN_KEY = "token";

private String token = null;

 protected CustomAuthenticationFilter(String defaultFilterProcessesUrl) {

    super(defaultFilterProcessesUrl);
    super.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(defaultFilterProcessesUrl));
    setAuthenticationManager(new CustomAuthenticationManager());
    setAuthenticationSuccessHandler(new CustomAuthenticationSuccessHandler());
 }

@Override
public Authentication attemptAuthentication(HttpServletRequest req,
        HttpServletResponse res)
        throws org.springframework.security.core.AuthenticationException,
        IOException, ServletException {     

    HttpServletRequest request = (HttpServletRequest)req;
    HttpServletResponse response = (HttpServletResponse)res;

     //get token value from request parameter
     token = request.getParameter(SECURITY_TOKEN_KEY);

     if(StringUtils.isBlank(token)){  
         try{
             token = request.getSession().getAttribute(SECURITY_TOKEN_KEY).toString();
         }catch(Exception ex){
             logger.info("Cannot get token");
        }            
     }

     AbstractAuthenticationToken userAuthenticationToken = null;

     try {
         userAuthenticationToken = authUserByToken(token);
    } catch (Exception e) {
        logger.error("error " + e);     
    }

    return userAuthenticationToken;
}

 @Override
 public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        super.doFilter(req, res, chain);
 }


 private AbstractAuthenticationToken authUserByToken(String token) throws Exception{
     if(StringUtils.isBlank(token)){
         return null;
     }

CustomAuthenticationToken

public class CustomAuthenticationToken extends AbstractAuthenticationToken{

    private static final long serialVersionUID = 1L;

    public CustomAuthenticationToken (String token){
        super(null);

        if(token.equals("abc")){
            super.setAuthenticated(true);
        }else{
            super.setAuthenticated(false);
        } 
    }

    @Override
    public Object getCredentials() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object getPrincipal() {
        // TODO Auto-generated method stub
        return null;
    }

}

CustomAuthenticationEntryPoint

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint{

    protected final Log logger = LogFactory.getLog(this.getClass());

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception) throws IOException, ServletException {
        String contentType = request.getContentType();
        logger.info(contentType);
        response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" );

    }

}

CustomAuthenticationManager

public class CustomAuthenticationManager implements AuthenticationManager{

    @Override
    public Authentication authenticate(Authentication paramAuthentication)
            throws AuthenticationException {
        // TODO Auto-generated method stub
        return paramAuthentication;
    }

}

CustomAuthenticationSuccessHandler

public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler  {

    @Override
    protected String determineTargetUrl(HttpServletRequest request,
            HttpServletResponse response) {
        String context = request.getContextPath();
        String fullURL = request.getRequestURI();
        String url = fullURL.substring(fullURL.indexOf(context)+context.length());
        return url;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        String url = determineTargetUrl(request,response);
        request.getRequestDispatcher(url).forward(request, response);
    }

}

的applicationContext-security.xml文件

<sec:http pattern="/test/**" entry-point-ref="customAuthenticationEntryPoint" use-expressions="true" auto-config="false" create-session="stateless" >
        <sec:custom-filter ref="customAuthenticationFilter" position="PRE_AUTH_FILTER"/>                
        <sec:intercept-url pattern="/test/**" access="isAuthenticated()"/>
        <sec:logout/>
    </sec:http> 

    <bean id="customAuthenticationFilter" class="com.security.CustomAuthenticationFilter">              
        <constructor-arg type="java.lang.String" value="/test/**"></constructor-arg>
    </bean>

    <bean id="customAuthenticationManager" class="com.security.CustomAuthenticationManager"></bean>

    <bean id="customAuthenticationEntryPoint" class="com.security.CustomAuthenticationEntryPoint"/>

    <sec:authentication-manager></sec:authentication-manager>

我会以正确的方式前进吗?请帮我解决这些问题。

0 个答案:

没有答案