Spring Security 之security.xml详解

简单说明一下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;
	}
}


转载于:https://my.oschina.net/kimyeongnam/blog/503653

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值