最近公司做一项目要用到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 Security3Springsecuritysecurity3
一. 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 Security3Springsecuritysecurity3
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;
}
}
<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>
<authentication-provider 这里不用 ref = 'authProvider' 吗 //这个authProvider是你自定义的
user-service-ref="myUserDetailService">
<!-- 如果用户的密码采用加密的话,可以加点“盐”
<password-encoder hash="md5" />-->
</authentication-provider>
</authentication-manager>其实你自己去拦截,还不如用它原有的类,继承一下就好了,