简单说明一下springsecurity的原理(此段摘自网络)
1.AccessDecisionManager
和我们一般实现登录验证采用filter的方式一样,springsecurity也是一个过滤器,当请求被springsecurity拦截后,会先对用户请求的资源进行安全认证,如果用户有权访问该资源,则放行,否则将阻断用户请求或提供用户登录,在springsecurity中,负责对用户的请求资源进行安全认证的是AccessDecisionManager,它就是一组投票器的集合,默认的策略是使用一个AffirmativeBased,既只要有一个投票器通过验证就允许用户访问,
所以如果希望实现自己的权限验证策略,实现自己的投票器是一个很好的选择。
2.UserDetailsService
如果用户没有登录就访问某一个受保护的资源,则springsecurity会提示用户登录,用户登录后,由UserDetailService来验证用户是否合法,既验证用户名和密码是否正确,同时验证用户是否具备相应的资源权限,
即对应的access的value。如果用户验证通过,则由AccessDecisionManager来决定是否用户可以访问该资源。
1.security.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 下面的一坨是一些XML的一些规范,我是这么理解的 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 下面是不需要进行认证的资源 -->
<security:http pattern="/js/**" security="none"/>
<!-- 因为要使用自己的权限验证规则,下面是配置一些自定义的Handler -->
<security:http auto-config="true" access-decision-manager-ref="accessDecisionManager">
<security:form-login login-page="/login.jsp" login-processing-url="/login" username-parameter="username"
password-parameter="password" authentication-success-handler-ref="myAuthenticationSuccessHandler" authentication-failure-handler-ref="myAuthenticationFailureHandler"/>
<security:logout logout-url="/logout" success-handler-ref="myLogoutSuccessHandler"/>
<!-- 下面开始配置针对某些权限,所能访问到的url -->
<security:intercept-url pattern="/adminHome*" access="ADMIN_MANAGE,MEMBER_MANAGE,GOODS_MANAGE,ORDER_MANAGE"/>
<security:intercept-url pattern="/user/manageMember*" access="MEMBER_MANAGE"/>
。。。。
<security:intercept-url pattern="/user/manageAdmin*" access="ADMIN_MANAGE"/>
。。。。
<security:intercept-url pattern="/book/manage*" access="GOODS_MANAGE"/>
。。。。
<security:intercept-url pattern="/order/manageOrder*" access="ORDER_MANAGE"/>
。。。。
<security:intercept-url pattern="/user/selfHome/*" access="WEBSITE_USE"/>
<!-- 下面是配置的自定义的访问拒绝的控制 -->
<security:access-denied-handler ref="myAccessDenied"/>
</security:http>
<!-- 认证管理器,使用自定义的UserDetailsService -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="myUserDetailsService">
</security:authentication-provider>
</security:authentication-manager>
<!-- 访问决策管理器,这里使用AffirmativeBased -->
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg name="decisionVoters">
<list>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
<property name="rolePrefix" value=""></property>
</bean>
<bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
</beans>
2.web.xml
<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>
3.自定义的Handler(细节问题较多,仅供参考)
MyAuthenticationFailureHandler.java
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler{
@Override
public void onAuthenticationFailure(HttpServletRequest request,HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
if(exception instanceof LockedException){
request.setAttribute("status","账户被封,请联系管理员");
}else{
request.setAttribute("status","用户名或密码错误");
}
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
MyAuthenticationSuccessHandler.java
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Resource
private UserDetailsService myUserCredentialProvider;
@Override
public void onAuthenticationSuccess(HttpServletRequest request,HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
String username = SecurityContextHolder.getContext().getAuthentication().getName();
UserCredential userCredential = (UserCredential) myUserCredentialProvider.loadUserByUsername(username);
Set<Role> roles = userCredential.getUser().getRoles();
for(Role role:roles){
if(role.getName().equals("MEM_COMMON")){
response.sendRedirect(request.getContextPath()+ "/");
return;
}
}
for(Role role:roles){
if(role.getName().matches("^ADM_.*")){
response.sendRedirect(request.getContextPath()+ "/adminHome");
return;
}
}
}
}
MyLogoutSuccessHandler.java
@Component
public class MyLogoutSuccessHandler implements LogoutSuccessHandler{
@Override
public void onLogoutSuccess(HttpServletRequest request,HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.sendRedirect(request.getContextPath()+ "/");
}
}
MyUserDetailsService.java
@Component
public class MyUserDetailsService implements UserDetailsService{
@Resource
private UserRepository userRepository;
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserCredential userCredential = new UserCredential(userRepository.selectUserSecurity(username));
if(userCredential.getUser() == null){
throw new UsernameNotFoundException("");
}
return userCredential;
}
}
UserCredential.java
public class UserCredential implements UserDetails {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public UserCredential(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
GrantedAuthority authority = null;
for(Role role : getUser().getRoles()){
for(Authority auth : role.getAuthorities()){
authority = new SimpleGrantedAuthority(auth.getName());
authorities.add(authority);
}
}
return authorities;
}
@Override
public String getPassword() {
return getUser().getPassword();
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return getUser().getUsername();
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
if(user.isNonlocked()){
return true;
}
return false;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}