当前位置:编程学习 > JAVA >>

Spring Security3 + S2SH认证问题!!!!

     最近公司做一项目要用到Spring Security3架构,所以搭了个测试环境,测试后发现登录认证没有走自定义的认证类,访问授权的没问题!希望各位高手多指点!!!下面是各部分代码!
      
一. 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>

二. applicationContext-security.xml
   
    <?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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" access-denied-page="/403.jsp"><!-- 当访问被拒绝时,会转到403.jsp -->
    
        <intercept-url pattern="/login.jsp" filters="none" />
        <form-login login-page="/login.jsp"
            authentication-failure-url="/login.jsp?error=true"
            default-target-url="/index.jsp" />
        <logout logout-success-url="/login.jsp" />
        <http-basic />
        
        <session-management>  
           <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login.jsp"/>  
        </session-management>  
        
        <!-- 增加一个filter,这个filter位于FILTER_SECURITY_INTERCEPTOR之前 -->
        <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR" />
    </http>
     

    <!-- 一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性,
    我们的所有控制将在这三个类中实现,解释详见具体配置 -->
    <beans:bean id="myFilter" class="com.zyht.pms.security.MyFilterSecurityInterceptor">
        <beans:property name="authenticationManager"  ref="authenticationManager" />
        <beans:property name="accessDecisionManager"  ref="myAccessDecisionManagerBean" />
        <beans:property name="securityMetadataSource"  ref="securityMetadataSource" />
    </beans:bean>
    
    <!-- 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 -->
    <authentication-manager alias="authenticationManager">
        <authentication-provider
            user-service-ref="myUserDetailService">
            <!-- 如果用户的密码采用加密的话,可以加点“盐”
                <password-encoder hash="md5" />-->
         </authentication-provider>
    </authentication-manager>
    
    <beans:bean id="myUserDetailService"
        class="com.zyht.pms.security.MyUserDetailService" />

    <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 -->
    <beans:bean id="myAccessDecisionManagerBean"
        class="com.zyht.pms.security.MyAccessDecisionManager">
    </beans:bean>
    
    <!-- 资源源数据定义,即定义某一资源可以被哪些角色访问 -->
    <beans:bean id="securityMetadataSource"
        class="com.zyht.pms.security.MyInvocationSecurityMetadataSource" />
      
</beans:beans>

三。 MyFilterSecurityInterceptor类
    
   public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter{

private FilterInvocationSecurityMetadataSource securityMetadataSource;

    // ~ Methods
    // ========================================================================================================

    /**
     * Method that is actually called by the filter chain. Simply delegates to
     * the {@link #invoke(FilterInvocation)} method.
     * 
     * @param request
     *            the servlet request
     * @param response
     *            the servlet response
     * @param chain
     *            the filter chain
     * 
     * @throws IOException
     *             if the filter chain fails
     * @throws ServletException
     *             if the filter chain fails
     */
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        FilterInvocation fi = new FilterInvocation(request, response, chain);
        invoke(fi);
    }

    public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
        return this.securityMetadataSource;
    }

    public Class<? extends Object> getSecureObjectClass() {
        return FilterInvocation.class;
    }

    public void invoke(FilterInvocation fi) throws IOException,
            ServletException {
        InterceptorStatusToken token = super.beforeInvocation(fi);
        try {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } finally {
            super.afterInvocation(token, null);
        }
    }

    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return this.securityMetadataSource;
    }

    public void setSecurityMetadataSource(
            FilterInvocationSecurityMetadataSource newSource) {
        this.securityMetadataSource = newSource;
    }

    public void destroy() {
    }

    public void init(FilterConfig arg0) throws ServletException {
    }


}
四。myUserDetailService类

    public class MyUserDetailService implements UserDetailsService {

private UserDao userDao = null;

public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}

public UserDetails loadUserByUsername(String loginName)
throws UsernameNotFoundException, DataAccessException {
// TODO Auto-generated method stub

SjyUser loginUser = userDao.findUserByName(loginName);

if(null != loginUser){

Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();

String[] roles = loginUser.getRoles().split(",");

GrantedAuthorityImpl auth = null;
for(int i = 0; i < roles.length; i++){
auth = new GrantedAuthorityImpl(roles[i]);
auths.add(auth);
}

User user = new User(loginName,
loginUser.getPassword(), true, true, true, true, auths);
        return user;

}

return null;
}

}
五。 MyAccessDecisionManager类

    public class MyAccessDecisionManager implements AccessDecisionManager {

public void decide(Authentication authentication, Object object,
Collection<ConfigAttribute> configAttributes) throws AccessDeniedException,
InsufficientAuthenticationException {
// TODO Auto-generated method stub

if(configAttributes == null){
          return ;
        }
                <!--由于登录没走认证类,所以这里修改为从session中获得用户信息-->
SjyUser user = (SjyUser)ServletActionContext.getRequest().getSession().getAttribute("loginUser");

        Iterator<ConfigAttribute>  ite = configAttributes.iterator();
        while(ite.hasNext()){
            ConfigAttribute ca=ite.next();
            String needRole=((SecurityConfig)ca).getAttribute();
            String[] roles = user.getRoles().split(",");
            for(int i = 0; i < roles.length; i++){
                if(needRole.equals(roles[i])){
                    return;
                }
            }
          <!--标准方式如下-->

            /*for(GrantedAuthority ga:authentication.getAuthorities()){
                if(needRole.equals(ga.getAuthority())){  //ga is user's role.
                    return;
                }
            }*/
        }
        throw new AccessDeniedException("no right");

}

public boolean supports(ConfigAttribute arg0) {
// TODO Auto-generated method stub
return true;
}

public boolean supports(Class<?> arg0) {
// TODO Auto-generated method stub
return true;
}

}
六。MyInvocationSecurityMetadataSource类

    public class MyInvocationSecurityMetadataSource implements
FilterInvocationSecurityMetadataSource {

private SysmenuDao sysmenuDao = null;
private UrlMatcher urlMatcher = new AntUrlPathMatcher();;
private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

public void setSysmenuDao(SysmenuDao sysmenuDao) {
this.sysmenuDao = sysmenuDao;
}

public MyInvocationSecurityMetadataSource() {
}

public MyInvocationSecurityMetadataSource(SysmenuDao sysmenuDao) {
this.sysmenuDao = sysmenuDao;
loadResourceDefine();
}

private void loadResourceDefine() {
List<SjySysmenu> sysmenus = sysmenuDao.selectSysmenuAll();

if (null != sysmenus && sysmenus.size() > 0) {
resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
Collection<ConfigAttribute> atts = null;

ConfigAttribute ca = null;
String[] roles = null;
for(SjySysmenu ss : sysmenus){

atts = new ArrayList<ConfigAttribute>();
roles = ss.getVisibleroles().split(",");

for(int i = 0; i < roles.length; i++){
ca = new SecurityConfig(roles[i]);
atts.add(ca);
}
resourceMap.put(ss.getLinkstr(), atts);
}
}

}

public Collection<ConfigAttribute> getAttributes(Object object)
throws IllegalArgumentException {
// TODO Auto-generated method stub

String url = ((FilterInvocation)object).getRequestUrl();
        Iterator<String> ite = resourceMap.keySet().iterator();
        while (ite.hasNext()) {
            String resURL = ite.next();
            if (urlMatcher.pathMatchesUrl(url, resURL)) {
                return resourceMap.get(resURL);
            }
        }
        return null;
}

public boolean supports(Class<?> arg0) {
// TODO Auto-generated method stub
return true;
}

public Collection<ConfigAttribute> getAllConfigAttributes() {
// TODO Auto-generated method stub
return null;
}
}
Spring Security3 Spring security security3 --------------------编程问答-------------------- 七。action

   public class userAction extends ActionSupport {

private SjyUser user = null;
private UserService userService = null;

public SjyUser getUser() {
return user;
}

public void setUser(SjyUser user) {
this.user = user;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public String execute() throws Exception {
SjyUser loginUser = userService.findUserByNameAndPassword(user.getLoginName(), user.getPassword());
ServletActionContext.getRequest().getSession().setAttribute("loginUser", loginUser);
if(null != loginUser){
return this.SUCCESS;
}
return this.INPUT;
}
}

--------------------编程问答-------------------- 八。jsp

 <body>
    <s:form action="/userAction" method="post">
<s:textfield name="user.loginName" label="用户名"></s:textfield>
<s:textfield name="user.password" label="密码"></s:textfield>
<s:submit value="登录"></s:submit>
</s:form>
  </body> --------------------编程问答-------------------- 对了,当登录的时候并不走myUserDetailService类!!!!! --------------------编程问答--------------------     <authentication-manager alias="authenticationManager">
        <authentication-provider  这里不用 ref = 'authProvider' 吗 //这个authProvider是你自定义的 
            user-service-ref="myUserDetailService"> 
            <!-- 如果用户的密码采用加密的话,可以加点“盐”
                <password-encoder hash="md5" />-->
         </authentication-provider>
    </authentication-manager>

其实你自己去拦截,还不如用它原有的类,继承一下就好了,
--------------------编程问答-------------------- 建议不要用自己写的FilterSecurityInterceptor实现类,除非你自己认为写的很完美才去重写一个,不然还是用默认的那个实现比较好,你可以参考下我博客里那些security文章,我个人比较喜欢用bean方式的,虽然是烦琐点,但是灵活性大大的增强,想怎么配置过滤链也可以
补充:Java ,  Web 开发
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,