因为一些原因,我需要自定义自己的UsernamePasswordAuthenticationFilter,之后把<form-login>标签去掉了,然后<session> <logout><session>等标签之间的配合好像都失效了?然后就把这几个过滤器都重自定义一下。需要自定义其它过滤器吗? 我需要一个过滤器或者其它相关过滤器的配置。在自定义登录验证过滤器之后,<session>,<logout>等标签配置好像失效了。这正常吗?
这里是一个问题:是不是自定义UsernamePasswordAuthenticationFilter之后相关的这几个过滤器都必须实现,而不能再继续使用<logout>等标签了。
<?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:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="false" entry-point-ref="loginUrlAuthenticationEntryPoint">
<csrf disabled="true"/>
<intercept-url pattern="/login.html" access="permitAll"/>
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/about" access="permitAll" />
<intercept-url pattern="/login" access="permitAll"/>
<intercept-url pattern="/user/**" access="hasRole('USER')" />
<intercept-url pattern="/admin/**" access="hasRole('ADMIN')" />
<!-- 这个要在最后一个拦截,否则会匹配上,/user,/admin都将失效(未验证) -->
<intercept-url pattern="/**" access="hasRole('USER')" />
<access-denied-handler error-page="/accessDenide" />
<!-- <session-management session-fixation-protection="migrateSession">
<concurrency-control max-sessions="1" expired-url="/login?error=expired"
/> </session-management> -->
<custom-filter ref="ipFilter" before="FILTER_SECURITY_INTERCEPTOR" />
<custom-filter ref="concurrencyFilter" position="CONCURRENT_SESSION_FILTER" />
<custom-filter ref="usernamePasswordAuthenticationFilter"
position="FORM_LOGIN_FILTER" />
<custom-filter ref="rememberMeFilter" position="REMEMBER_ME_FILTER" />
<custom-filter ref="logoutFilter" position="LOGOUT_FILTER" />
<!-- <remember-me key="Bay1ts" remember-me-parameter="remember-me" token-validity-seconds="604800"
data-source-ref="dataSource" user-service-ref="customjdbcUserService" />
<form-login login-page="/login" default-target-url="/" password-parameter="pwd"
/> <logout logout-success-url="/about" logout-url="/logout"/> -->
</http>
<!-- 注意这里,<beans:bean id="">的写法 -->
<!-- 注意这里这些属性,其实可以不设置的,本来里面就有static的这些String,表示默认的,但如果你的数据库不是这样的模式,就该自己指定了,像这样。 -->
<!-- 因为配置了passwordEncoder,导致输入的密码到数据库比较时都已经是加密过的了,这个是为了在启动时把数据库里的密码加密一下就能匹配了。 -->
<!-- 只能运行一次,不然会把密文再加密一次 -->
<!-- 明文密码加密加盐器!!!!!! -->
<!-- <beans:bean class="com.bay1ts.security.DatebasePasswordSecurityUpdater"
init-method="secureDatabase" depends-on="dataSource"> <beans:property name="dataSource"
ref="dataSource" /> </beans:bean> -->
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:constructor-arg name="sessionRegistry"
ref="sessionRegistry" />
<beans:constructor-arg name="expiredUrl"
value="/login?error=expired" />
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="http403EntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint">
</beans:bean>
<beans:bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:constructor-arg name="loginFormUrl"
value="/login.html" />
</beans:bean>
<beans:bean id="sas"
class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
<!--
<beans:constructor-arg>
<beans:list>
<beans:bean
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
<beans:property name="exceptionIfMaximumExceeded"
value="true" />
</beans:bean>
<beans:bean
class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
</beans:bean>
<beans:bean
class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry" />
</beans:bean>
</beans:list>
</beans:constructor-arg>
-->
<beans:property name="migrateSessionAttributes" value="true"/>
</beans:bean>
<beans:bean id="rememberMeFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<beans:constructor-arg name="authenticationManager"
ref="authenticationManager" />
<beans:constructor-arg name="rememberMeServices"
ref="rememberMeServices" />
</beans:bean>
<beans:bean id="usernamePasswordAuthenticationFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="rememberMeServices" ref="rememberMeServices" />
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="filterProcessesUrl" value="/login" />
<beans:property name="authenticationFailureHandler"
ref="failureHandler" />
<beans:property name="authenticationSuccessHandler"
ref="successHandler" />
<beans:property name="sessionAuthenticationStrategy"
ref="sas" />
</beans:bean>
<beans:bean id="successHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/" />
</beans:bean>
<beans:bean id="failureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.html" />
</beans:bean>
<beans:bean id="logoutHandler"
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
<beans:bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg name="logoutSuccessUrl"
value="/" />
<beans:constructor-arg>
<beans:array>
<beans:ref local="logoutHandler" />
<beans:ref local="rememberMeServices" />
</beans:array>
</beans:constructor-arg>
<beans:property name="filterProcessesUrl" value="/logout" />
</beans:bean>
<beans:bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<beans:constructor-arg name="key" value="Bay1ts" />
<beans:constructor-arg name="userDetailsService"
ref="customjdbcUserService" />
<beans:constructor-arg name="tokenRepository"
ref="tokenRepository" />
</beans:bean>
<beans:bean id="tokenRepository" class="com.bay1ts.security.CustomTokenRepository">
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<beans:bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<beans:constructor-arg name="key" value="Bay1ts" />
</beans:bean>
<beans:bean id="customjdbcUserService" class="com.bay1ts.security.CustomJdbcDaoImpl">
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<beans:bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" />
<beans:bean id="saltSource"
class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<beans:property name="userPropertyToUse" value="username" />
</beans:bean>
<beans:bean id="ipFilter"
class="com.bay1ts.security.IPRoleAuthenticationFilter">
<beans:property name="targetRole" value="ADMIN" />
<beans:property name="allowedIPAddresses">
<beans:list>
<beans:value>0:0:0:0:0:0:0:1</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customjdbcUserService">
<password-encoder ref="passwordEncoder">
<salt-source ref="saltSource" />
</password-encoder>
</authentication-provider>
<authentication-provider ref="rememberMeAuthenticationProvider" />
</authentication-manager>
</beans:beans>
之后
login.html的主要部分:
<form action="/login" method=post>
<div class="input-container">
<input type="text" id="Username" name="username" required="required"/>
<label for="用户名">Username</label>
<div class="bar"></div>
</div>
<div class="input-container">
<input type="password" id="Password" name="password" required="required"/>
<label for="密码">Password</label>
<div class="bar"></div>
</div>
<div class="checkbox">
<input type="checkbox" id="Remember-me" name="remember-me"/>
<label for="Remember-me">Remember-me</label>
<div class="checkbox"></div>
</div>
<div class="button-container">
<button><span>Go</span></button>
</div>
<div class="footer"><a href="#">忘记密码?</a></div>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
这是basecontroller
@RequestMapping("/login")
public void login(){
}
@RequestMapping(value="/login",params="error")
public String login(@RequestParam("error")String error,Model model){
model.addAttribute("errormsg", error);
return "error_expired";
}
@RequestMapping("/about")
public String about(){
return "about";
}
@ModelAttribute("numUsers")
public int getNumberOfCurrentUsers(){
System.out.println(SessionRegistry);
for(Object o:SessionRegistry.getAllPrincipals()){
System.out.println(o.toString());
}
return SessionRegistry.getAllPrincipals().size();
}
这是web.xml相关部分
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher</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>
并且我禁用了csrf功能,如果不禁用的话说网页包含循环定向。
但是现在,我觉着应该对session(会话)的处理还有很大缺陷,因为/index下有统计当前已登录用户数量的功能,现在一直是0,并且session的并发控制失效了,在另外一浏览器上登陆时不能顶下去原来登陆的用户了。所以现在的问题,大概就是csrf问题,和session的问题了。
希望大家指导一下大三党,弄了好久了,在这样下去效率太低了。多谢大家啦!