spring-security学习

spring-security有两种方法显示比较简单的配置userDetailService

1、   简单实现用户名和密码、权限的验证(使用默认的过滤器)

spring-securit使用authenticationManager来校验用户名和密码,authenticationManager是依靠其包含一系列authenticationProvider完成验证的, 如果配置只没有指明authenticationProvider默认DoAuthenticationProvider,只要指明其UserService就可以。如下图:

<?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"
             xsi:schemaLocation="http://www.springframework.org/schema/beans 
             					http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              					http://www.springframework.org/schema/security               					http://www.springframework.org/schema/security/spring-security-3.0.xsd">       

    <http auto-config="true">     
        <intercept-url pattern="/login.jsp" filters="none"/> 
        <form-login login-page="/login.jsp"
        login-processing-url="/j_security_check"
        authentication-success-handler-ref="loginHandler"
        authentication-failure-handler-ref="loginHandler"/>
        <logout success-handler-ref="loginHandler"/>
        <intercept-url pattern="/admin/**" access="ROLE_ADMIN,ROLE_USER"/>
    </http>
    <authentication-manager">
        <authentication-provider user-service-ref="userService"/>
    </authentication-manager>
</beans:beans>

其中userService要实现UserDetailsService接口,其中的关键方法是 UserDetails loadUserByUsername( String username ).

这个方法返回一个UserDetails的接口,我们需要我们的User类实现UserDetails接口,其中的关键方法是              Collection<GrantedAuthority> getAuthorities(), 这个方法返回一个GrantedAuthority接口的集合。

UserDetails接口可以返回用户名,密码,权限的集合Collection<GrantedAuthority>,是否停用等信息。

我们可以让Role实现这个接口,其中关键方法是  String getAuthority(),即返回权限字符串,如ROLE_ADMIN。

UserService主要内容

 

@Repository("userService")

public class UserService implements UserDetailsService{

@Autowired
private HibernateTemplate hibernateTemplate;

public UserDetails loadUserByUsername(String username)
    throws UsernameNotFoundException, DataAccessException {
    List<User> list = hibernateTemplate.find("from User where username=?",username);
    if(list == null || list.size()==0)   
           throw new UsernameNotFoundException("用户" + username + " 不存在!!!");  
    User user = list.get(0);
    return user;  
    }
}

2、在spring-security.xml中配置验证自定义的过滤器(在1步骤的基础上)

spring-security中需要配置验证过滤器来实现整个拦截的过程,其中需要配置一下三个来实现。

authenticationManager:第一步已经完成配过。判断用户名和密码是否相等。

securityMetadataSource:根据url得到需要的角色名称FilterInvocationSecurityMetadataSource.getAttributes()方法实现,需要初始化所有url对应的角色(可以放到初始化函数或者构造函数)

accessDecisionManager:将根据上面得到url需要的角色与用户角色对比,有相等则通过,AccessDecisionManager.decide()方法实现。

 

security.xml配置    

<?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"
             xsi:schemaLocation="http://www.springframework.org/schema/beans 
             					http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              					http://www.springframework.org/schema/security               					http://www.springframework.org/schema/security/spring-security-3.0.xsd">       

<http auto-config="true">     
    <intercept-url pattern="/login.jsp" filters="none"/> 
    <form-login login-page="/login.jsp"
    login-processing-url="/j_security_check"
    authentication-success-handler-ref="loginHandler"
    authentication-failure-handler-ref="loginHandler"/>
    <logout success-handler-ref="loginHandler"/>
    <intercept-url pattern="/admin/**" access="ROLE_ADMIN,ROLE_USER"/>
    <custom-filter ref="myFilterSecurityInterceptor"         before="FILTER_SECURITY_INTERCEPTOR" />
    </http>

    <beans:bean id="myFilterSecurityInterceptor" class="com.wxg.general.MyFilterSecurityInterceptor">
        <beans:property name="authenticationManager" ref="myAuthenticationManager" />
        <beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
        <beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
    </beans:bean>

    <authentication-manager alias="myAuthenticationManager">
        <authentication-provider user-service-ref="userDao">
        </authentication-provider>
    </authentication-manager>

</beans:beans>

   MyFilterSecurityInterceptor.java的主要方法

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
        FilterInvocation fileInvocation = new FilterInvocation(request, response, chain);
        //验证权限在beforeInvocation方法中
        InterceptorStatusToken interceptorStatusToken =  this.beforeInvocation(fileInvocation);
        System.out.println("FilterSecurityInterceptor -method-doFiler");
        fileInvocation.getChain().doFilter(request, response);
        this.afterInvocation(interceptorStatusToken, null);
}

MySecurityMetadataSource 主要内容

@Controller("mySecurityMetadataSource")
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
private Map<String, List<ConfigAttribute>> mp;
private UrlMatcher urlMatcher;

    public MySecurityMetadataSource()
     {
    //构造函数初始化,必须把所有菜单配上权限放入mp
         super();
         this.mp = new HashMap<String, List<ConfigAttribute>>();
         this.urlMatcher = new AntUrlPathMatcher();
         List<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
         ConfigAttribute cb = new SecurityConfig("ROLE_ADMIN"); // 构造一个权限(角色)
         ConfigAttribute cbUser = new SecurityConfig("ROLE_USER"); // 构造一个权限(角色)
         list.add(cb);
         list.add(cbUser);     
         mp.put("/admin/adminMenu.jsp", list);
     }

    public Collection<ConfigAttribute> getAttributes(Object object)
        throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation) object).getRequestUrl();
        Iterator<String> iter = this.mp.keySet().iterator();
        while (iter.hasNext()) {
            String temp = iter.next();
            if (this.urlMatcher.pathMatchesUrl(requestUrl, temp)) {
                return mp.get(temp);
            }
        }
        return null;
    }
}

MyAccessDecisionManager  类主要内容

@Service( "myAccessDecisionManager" )
public class MyAccessDecisionManager  implements AccessDecisionManager {
    public void decide( Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes )
        throws AccessDeniedException, InsufficientAuthenticationException {
    //负责校验请求的url需要的权限,和登录权限是否有相等。
        Iterator<ConfigAttribute> ite = configAttributes.iterator();
        while ( ite.hasNext() ) {
            ConfigAttribute ca = ite.next();
            String needRole = ( (SecurityConfig) ca ).getAttribute();
            for ( GrantedAuthority ga : authentication.getAuthorities() ) {
                if ( ga.getAuthority().equals( "ROLE_ADMIN" ) || needRole.equals( ga.getAuthority() ) ) { 
                    return;
                }
            }
        }
        throw new AccessDeniedException( "没有权限" );
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值