springMVC+springSecurity 自实现UserDetailsService 使用@AutoWired 无法注入bean

xwbggg 2014-08-29 04:42:52
springMVC+springSecurity 自实现UserDetailsService 使用@AutoWired 无法注入bean 但是在其他类却可以正常注入
package com.fujitsu.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fujitsu.dao.UserDao;
import com.fujitsu.entity.Role;
import com.fujitsu.entity.User;
import com.fujitsu.service.UCenterService;
import com.fujitsu.service.serviceImpl.TestService;

/**
* 实现UserDetailsService 接口,主要是在loadUserByUsername方法中验证一个用户
* 这里需要从数据库中读取验证表单提交过来的用户
*
* @author xian.wenbing
*
*/
@Service
public class WebUserDetailsService implements UserDetailsService {
protected MessageSourceAccessor messages = SpringSecurityMessageSource
.getAccessor();

@Autowired
private UserDao userDao;



@Transactional
public UserDetails loadUserByUsername(String userName)
throws UsernameNotFoundException, DataAccessException {
User user = userDao.getSingleUser(userName);
if (user == null) {
throw new UsernameNotFoundException(messages.getMessage(
"User.notFound", new Object[] { userName },
"UserName {0} not found"));
}
int userId = user.getId();
String passWord = user.getPassWord();
boolean userEnabled = user.getStats() == 1;
// 读取当前用户有哪些角色权限
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
Set<Role> userRoles = user.getRoles();
for (Role userRole : userRoles) {
// 和WebSecurityMetadataSource中的SecurityConfig参数对应
GrantedAuthorityImpl authority = new GrantedAuthorityImpl("ROLE_"
+ userRole.getId());
authorities.add(authority);
}
// 创建 UserDetails 对象
WebUserDetails webUserDetails = new WebUserDetails(userId, userName,
passWord, userEnabled, authorities);

return webUserDetails;
}
}
package com.fujitsu.service.serviceImpl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fujitsu.dao.MenuDao;
import com.fujitsu.dao.RoleDao;
import com.fujitsu.dao.UserDao;
import com.fujitsu.entity.Menu;
import com.fujitsu.entity.Role;
import com.fujitsu.entity.User;
import com.fujitsu.service.UCenterService;
@Service
public class UCenterServiceImpl implements UCenterService {
@Autowired
private UserDao userDao;
@Autowired
private MenuDao menuDao;
@Autowired
private RoleDao roleDao;

public Menu getMenu(int id) {
return menuDao.getMenuById(id);
}

public Role getRole(int id) {

return roleDao.getRoleById(id);
}

public User getUserByUserName(String userName) {
return userDao.getSingleUser(userName);
}

public List<Role> getAvailableRoles() {
return this.roleDao.getRolesByStatus(1);
}

public List<Menu> getAllMenus() {
return this.menuDao.getAllMenus();
}

}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<context:annotation-config />
<!-- 把标记了@Controller注解的类转换为bean -->
<context:component-scan base-package="com.fujitsu" />
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

<!-- 对模型视图名称的解析,即在模型视图名称添加前后缀
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/view/" p:suffix=".jsp" />
-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:defaultEncoding="utf-8" />
<!-- 开启Sping注释管理事务功能,指定事务管理的Bean -->
<tx:annotation-driven transaction-manager="txManager" />
<!-- end -->
<!-- 关于返回页面的 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>


</beans>
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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">
<!--
开启支持方法注解的权限控制:
@PreAuthorize:该注解用来确定一个方法是否应该被执行。该注解后面跟着一个表达式。若表达式为真,则该方法执行
@PreAuthorize("hasRole('ROLE_USER')")只有当前用户具有角色ROLE_USER的时候才会执行
@PostAuthorize:该注解用来在方法执行完后进行访问控制检查
@PostFilter:该注解用来对方法的返回结果过滤。从返回的集合中过滤掉表达式值为假的元素。如@PostFilter("
hasPermission(filterObject,'read')")说明返回的结果中保留当前用户有读权限的元素。 @PreFilter:
用来对方法调用时的参数进行过滤
-->
<security:global-method-security
pre-post-annotations="enabled" />
<!-- 不用过滤的
<security:http pattern="" security="none" />
-->
<security:http use-expressions="true"
entry-point-ref="authenticationProcessingFilterEntryPoint"
access-denied-page="">
<!-- 指定某角色能访问的资源 -->
<security:intercept-url pattern="/super/**"
access="hasRole('ROLE_SUPER')" />
<security:intercept-url pattern="/login.jsp*"
filters="none" />
<!-- 以上未列出的,必须验证才能访问 -->
<security:intercept-url pattern="/**"
access="isAuthenticated()" />
<!--
logout-url 属性:这个指定的URL会触发注销操作,默认是 /j_spring_security_logout
invalidate-session 属性:如果为true,在注销的时候会销毁会话 delete-cookies
属性:以逗号分隔的cookies名称,在用户注销时删除指定的cookies
-->
<security:logout logout-success-url="/logout.jsp"
invalidate-session="true" />
<!--
session超时跳转页面 以及每用户可拥有的session最大个数 如果每次退出后,必须要求用户必须重开浏览器才能登录,可以将
invalid-session-url="/logout.jsp",防止有些 Web 应用把用户的会话标识符直接通过 URL 的参数来传递
-->
<security:session-management
invalid-session-url="/logout.jsp">
<security:concurrency-control
max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login" />
</security:session-management>
<!-- 验证码过滤器 -->
<security:custom-filter ref="validateAuthenticationFilter"
position="FORM_LOGIN_FILTER" />

<!-- 使用自定义的过滤器 -->
<security:custom-filter ref="webSecurityFilter"
before="FILTER_SECURITY_INTERCEPTOR" />
</security:http>

<!-- 配置登录入口点 -->
<bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login" />
<!-- 是否强制HTTPS -->
<property name="forceHttps" value="false" />
</bean>

<!-- 配置自定义的支持验证码等多功能过滤器 -->
<bean id="validateAuthenticationFilter" init-method="init"
class="com.fujitsu.security.ValidateCodeUsernamePasswordAuthenticationFilter">
<property name="filterProcessesUrl" value="/doLogin"></property>
<property name="userNameParameter" value="userName"></property>
<property name="passWordParameter" value="passWord"></property>
<property name="successUrl" value="/index.jsp"></property>
<property name="failureUrl" value="/login"></property>
<property name="authenticationManager" ref="webAuthenticationManager"></property>
</bean>
<!-- 实现了 UserDetailsService 接口的类 -->
<security:authentication-manager alias="webAuthenticationManager">
<security:authentication-provider
user-service-ref="webUserDetailsService">
<!--
密码的加密解密类 <security:password-encoder ref="pwEncoder" />

<password-encoder hash="md5"/>
-->

</security:authentication-provider>
</security:authentication-manager>



<!--
使用SPRING注解方式,注释掉 authenticationManager:用户拥有的权限
accessDecisionManager:用户是否拥有所请求资源的权限 securityMetadataSource:资源与权限对应关系
-->
<bean id="webSecurityFilter" class="com.fujitsu.security.WebSecurityFilter">
<property name="authenticationManager" ref="webAuthenticationManager" />
<property name="accessDecisionManager" ref="webAccessDecisionManager" />
<property name="securityMetadataSource" ref="webSecurityMetadataSource" />
</bean>
<bean id="webAccessDecisionManager" class="com.fujitsu.security.WebAccessDecisionManager" />

<bean id="webSecurityMetadataSource" class="com.fujitsu.security.WebSecurityMetadataSource" />

<bean id="webUserDetailsService" class="com.fujitsu.security.WebUserDetailsService" >
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.fujitsu.dao.daoImpl.UserDaoImpl"/>
</beans>
...全文
4213 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Neomi 2017-02-22
  • 打赏
  • 举报
回复
可以试一下通过构造器注入
迷林 2015-07-29
  • 打赏
  • 举报
回复
看看你无法注入的Bean中的类名和属性名是不是一样 比如你的UserDao类,在Service中是不是叫做userDao如果不是,是不会帮你自动注入的
csdn_lichao 2015-07-29
  • 打赏
  • 举报
回复
敢问楼主 问题解决了吗 我也遇到同样的问题
tank2140896 2015-07-29
  • 打赏
  • 举报
回复
这个确实不知道怎么解决,我今天也研究了下,没办法,现在只想出了一个折中办法: 在你的WebUserDetailsService 中,不要写@Autowired private UserDao userDao; 如果你用mybatis直接注入: @Resource public SqlSessionFactory sqlSessionFactory; jdbcTemplate: @Resource public JdbcTemplate jdbcTemplate; hibernate: @Resource public SessionFactory sessionFactory; 接下来,由于我用的是mybatis,那么你原来的 User user = userDao.getSingleUser(userName); 现在写为: User user = sqlSessionFactory.openSession().selectOne("com.xxx.xxx.copyME.DemoTestDaoImpl.search",username);
zy_think123 2014-08-30
  • 打赏
  • 举报
回复
说说他们的区别,你从这两个方面去看看吧
1、@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。 
2、@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下: 
Java代码  收藏代码

    @Autowired() @Qualifier("baseDao")     
    private BaseDao baseDao;    

 3、@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定, 
如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
zy_think123 2014-08-30
  • 打赏
  • 举报
回复
不好意思我说错了哈,默认是按照类型的,你看看你相应的bean中时候写了注解呢?比如@Resource等
zy_think123 2014-08-30
  • 打赏
  • 举报
回复
@Autowired的默认值是ByName,所以你需要看看你无法注入的Bean中的类名和属性名是不是一样 比如你的UserDao类,在Service中是不是叫做userDao如果不是,是不会帮你自动注入的
愤怒的砖头 2014-08-30
  • 打赏
  • 举报
回复
你的dao是配置在配置文件里面的?不是用注解吗?你的其他dao放在拉什么地方

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧