Spring Security:自定义过滤后预授权

时间:2015-11-02 20:02:04

标签: spring spring-security spring-data spring-data-rest

我在spring security中创建了自己的自定义过滤器进行身份验证。

<security:custom-filter ref="restServicesFilter"  position="FIRST"/>

这是完整的security-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
    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/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/jdbc 
                           http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
                           http://www.springframework.org/schema/data/jpa
                           http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
                           http://www.springframework.org/schema/security
                           http://www.springframework.org/schema/security/spring-security.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">



<security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled"></security:global-method-security>


<security:http auto-config="false" authentication-manager-ref="authenticationManager" entry-point-ref="restAuthenticationEntryPoint" create-session="stateless">
<!--stateless for rest   -->
<security:custom-filter ref="restServicesFilter"  position="FIRST"/>



<security:access-denied-handler error-page="/error"/>
<security:csrf/>

</security:http>


<bean id="restServicesFilter"
class="com.pocdb.security.RestUsernamePasswordAuthenticationFilter">
<property name="postOnly" value="false" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="restServicesSuccessHandler" />
</bean>
<bean id="restServicesSuccessHandler"
class="com.pocdb.security.RestAuthenticationSuccessHandler" />


    <security:authentication-manager id="authenticationManager">
  <security:authentication-provider>
   <security:jdbc-user-service data-source-ref="dataSource"

    users-by-username-query="select username,password, enabled from users where username=?"
    authorities-by-username-query="select username, role from user_roles where username =?" />
  </security:authentication-provider>
 </security:authentication-manager> 



</beans>

我也使用Spring Data Rest,我的存储库看起来像这样

@RepositoryRestResource
@PreAuthorize("hasRole('ROLE_ADMIN')")
public interface TaskRepository extends CrudRepository<Task, Serializable>{
}

请注意使用PreAuthorize。

我的入门点类看起来像这样:

@Component
public final class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

    public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }

过滤类是:

public class RestUsernamePasswordAuthenticationFilter extends
        UsernamePasswordAuthenticationFilter {


    @Override
    protected boolean requiresAuthentication(HttpServletRequest request,
            HttpServletResponse response) {
        // TODO Auto-generated method stub

        boolean retVal = false;
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if (username != null && password != null) {
            Authentication authResult = null;
            try {
                authResult = attemptAuthentication(request, response);
                if (authResult == null) {
                    retVal = false;
                }
            } catch (AuthenticationException failed) {
                System.out.println("FUCKED");

            try {
                retVal=false;
                unsuccessfulAuthentication(request, response, failed);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ServletException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }   


            }

            FilterChain chain = null;
            try {
                retVal=false;
                successfulAuthentication(request, response, chain, authResult);
                retVal=true;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ServletException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }





        }
        return retVal;
    }

}

和SuccessHandler看起来像

public class RestAuthenticationSuccessHandler implements AuthenticationSuccessHandler{

    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
            //DO NOTHING???/?// after this will it go to PRE AUTHORIZE?

        System.out.println("SUCCESS HANDLER ");

    }

我假设在点击GET url&#39; / tasks?username?XXX&amp; password = XXX&#39;具有所需角色,我也将获得授权,并且能够查看json。

但是,在SuccessHandler类之后没有打印日志,并且请求未获得授权。我的自定义处理程序似乎工作得很好。但@PreAuthorize似乎没有用。 在浏览器上,我既没有看到错误页面:      也没有401     response.sendError(HttpServletResponse.SC_UNAUTHORIZED,&#34; Unauthorized&#34;); 但是一个完全空白的页面。所需的页面是一个json,显示了DB中存在的所有任务。

出了什么问题?

此外,我对EntryPoint类的begin()方法的理解也较少。 有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

停止此无意义并使用HTTP基本身份验证,然后添加N号自定义过滤器。

答案 1 :(得分:0)

点击请求一次后记录:请注意日志打印两次:也许是因为我有applicationContext和webContext创建bean,但这与@PreProcessor

无关
01:52:16.796 [btpool0-2] DEBUG o.s.security.web.FilterChainProxy - /tasks?username=Dipanshu&password=dipanshu at position 1 of 8 in additional filter chain; firing Filter: 'RestUsernamePasswordAuthenticationFilter'
01:52:16.802 [btpool0-2] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
01:52:16.811 [btpool0-2] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL query
01:52:16.811 [btpool0-2] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select username,password, enabled from users where username=?]
01:52:16.813 [btpool0-2] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
01:52:16.813 [btpool0-2] DEBUG o.s.j.d.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/zz]
01:52:16.856 [btpool0-2] DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
01:52:16.858 [btpool0-2] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL query
01:52:16.858 [btpool0-2] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select username, role from user_roles where username =?]
01:52:16.858 [btpool0-2] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
01:52:16.858 [btpool0-2] DEBUG o.s.j.d.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/zz]
01:52:16.863 [btpool0-2] DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
01:52:16.865 [btpool0-2] DEBUG c.p.s.RestUsernamePasswordAuthenticationFilter - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f5a6249a: Principal: org.springframework.security.core.userdetails.User@ee7a3e8: Username: Dipanshu; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER
SUCCESS HANDLER 
01:52:16.866 [btpool0-2] DEBUG c.p.s.RestUsernamePasswordAuthenticationFilter - Request is to process authentication
01:52:16.866 [btpool0-2] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
01:52:16.866 [btpool0-2] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL query
01:52:16.866 [btpool0-2] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select username,password, enabled from users where username=?]
01:52:16.866 [btpool0-2] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
01:52:16.866 [btpool0-2] DEBUG o.s.j.d.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/zz]
01:52:16.871 [btpool0-2] DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
01:52:16.871 [btpool0-2] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL query
01:52:16.871 [btpool0-2] DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select username, role from user_roles where username =?]
01:52:16.871 [btpool0-2] DEBUG o.s.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
01:52:16.871 [btpool0-2] DEBUG o.s.j.d.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/zz]
01:52:16.876 [btpool0-2] DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
01:52:16.877 [btpool0-2] DEBUG c.p.s.RestUsernamePasswordAuthenticationFilter - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f5a6249a: Principal: org.springframework.security.core.userdetails.User@ee7a3e8: Username: Dipanshu; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER
SUCCESS HANDLER