在我的自定义用户详细信息服务中,我的变量“aUserService”即使已经注释也不会自动连接。尝试了很多方法,但仍然失败,值为null。
我正在遵循krams教程。 http://krams915.blogspot.sg/2012/01/spring-security-31-implement_1244.html
这是我的项目https://skydrive.live.com/#cid=837EF1FA9A4C06AE&id=837EF1FA9A4C06AE%21130,环境:netbeans 7.2,maven,tomcat 7.0.39,postgresql 9.2,db sql在项目中。在META-INF / context.xml
定义的数据库池这是我的 的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>setEncoding</filter-name>
<filter-class>sg.com.innovax.opscentralv5.objects.setEncoding</filter-class>
</filter>
<filter-mapping>
<filter-name>setEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ================================ START Captha ================================ -->
<filter>
<filter-name>jcaptchaFilter</filter-name>
<filter-class>sg.com.innovax.jcaptcha.JCaptchaFilter</filter-class>
<init-param>
<param-name>failureUrl</param-name>
<param-value>/?error=true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jcaptchaFilter</filter-name>
<url-pattern>/jcaptcha.jpg</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>jcaptchaFilter</filter-name>
<url-pattern>/j_spring_security_check</url-pattern>
</filter-mapping>
<!-- ================================ END Captha ================================ -->
<!-- Spring Security -->
<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>
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security.xml
</param-value>
</context-param>
<!-- Creates the Spring Container shared by
all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<error-page>
<error-code>401</error-code>
<location>/WEB-INF/views/401.jsp</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/WEB-INF/views/403.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/views/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/views/500.jsp</location>
</error-page>
<resource-ref>
<description>postgreSQL</description>
<res-ref-name>jdbc/postgres</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<!-- solr server url -->
<context-param>
<param-name>solr_url</param-name>
<param-value>http://localhost:8080/solr</param-value>
</context-param>
</web-app>
my spring servlet xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
</beans:beans>
my 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:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<debug />
<global-method-security pre-post-annotations="enabled"/>
<http pattern="/resources/**" security="none"/>
<http pattern="/test/**" security="none"/>
<http pattern="/loggedout.jsp" security="none"/>
<http pattern="/forgotPassword" security="none"/>
<http pattern="/ProcessResetPassword" security="none"/>
<http pattern="/test" security="none"/>
<http pattern="/jcaptcha.jpg" security="none"/>
<http use-expressions="true">
<intercept-url pattern="/" access="permitAll"/>
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login login-processing-url="/j_spring_security_check"
login-page="/"
default-target-url="/user/"
always-use-default-target="true"
authentication-failure-url="/?error=true" />
<remember-me key="OpsCentral" token-validity-seconds="3600"/>
<logout logout-url="/j_spring_security_logout" />
</http>
<context:annotation-config />
<context:component-scan base-package="sg.com.innovax" />
<authentication-manager >
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder hash="sha"/>
</authentication-provider>
</authentication-manager>
<!-- Jcaptcha -->
<beans:bean id="captchaService"
class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService">
<beans:property name="captchaEngine">
<beans:bean class="sg.com.innovax.jcaptcha.GMailEngine" />
</beans:property>
<!-- 180 secs to expired
<property name="minGuarantedStorageDelayInSeconds" value="180" />
-->
</beans:bean>
</beans:beans>
我的root-context xml
<?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:jee="http://www.springframework.org/schema/jee"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
">
<context:annotation-config />
<context:component-scan base-package="sg.com.innovax" />
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Root Context: defines shared resources visible to all other web components -->
<jee:jndi-lookup id="dataSource"
jndi-name="jdbc/postgres"
expected-type="javax.sql.DataSource" />
<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<beans:property name="defaultLocale" value="en" />
</beans:bean>
<!-- Register the welcome.properties -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basename" value="welcome" />
</beans:bean>
<!-- JPA -->
<beans:bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<beans:property name="database" value="POSTGRESQL" />
</beans:bean>
</beans:property>
<beans:property name="packagesToScan" value="sg.com.innovax" />
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="emf" />
</beans:bean>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="100000000"/>
</beans:bean>
我的自定义用户详细信息服务
package sg.com.innovax.opscentralv5.objects;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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 sg.com.innovax.opscentralv5.table.service.UserService;
/**
* A custom {@link UserDetailsService} where user information
* is retrieved from a JPA repository
*/
@Service
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserService aUserService;
/**
* Returns a populated {@link UserDetails} object.
* The username is first retrieved from the database and then mapped to
* a {@link UserDetails} object.
*/
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
sg.com.innovax.opscentralv5.table.User u = aUserService.findByUsername(username);
String pass = sg.com.innovax.opscentralv5.table.User.byteToHex(u.getPassword());
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
return new User(
u.getUsername(),
pass,
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(1));
} catch (Exception e) {
System.out.println(e.toString());
throw new RuntimeException(e);
}
}
/**
* Retrieves a collection of {@link GrantedAuthority} based on a numerical role
* @param role the numerical role
* @return a collection of {@link GrantedAuthority
*/
public Collection<? extends GrantedAuthority> getAuthorities(Integer role) {
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
return authList;
}
/**
* Converts a numerical role to an equivalent list of roles
* @param role the numerical role
* @return list of roles as as a list of {@link String}
*/
public List<String> getRoles(Integer role) {
List<String> roles = new ArrayList<String>();
if (role.intValue() == 1) {
roles.add("ROLE_USER");
roles.add("ROLE_ADMIN");
} else if (role.intValue() == 2) {
roles.add("ROLE_USER");
}
return roles;
}
/**
* Wraps {@link String} roles to {@link SimpleGrantedAuthority} objects
* @param roles {@link String} of roles
* @return list of granted authorities
*/
public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}
我的用户服务工具
package sg.com.innovax.opscentralv5.table.service.impl;
import .....;
@Service("jpaUserService")
@Repository
@Transactional
public class UserServiceImpl implements UserService {
private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
@PersistenceContext
private EntityManager em;
@Transactional(readOnly=true)
public User findByUsername(String username) {
........
}
}
我的用户类
package sg.com.innovax.opscentralv5.table;
import ....;
@Entity
@Table(name = "users", uniqueConstraints = { @UniqueConstraint(columnNames = "username") })
@NamedQueries({
.....
})
public class User implements Serializable {
public static final String ROLE_ADMIN = "ROLE_ADMIN";
public static final String ROLE_USER = "ROLE_USER";
@Id
@SequenceGenerator(name="users_id_seq", sequenceName="users_id_seq", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="users_id_seq")
@Basic(optional = false)
private Integer id;
@Column(unique=true)
private String username;
private byte[] password;
private String email;
private String mobile;
private Boolean enabled;
private Timestamp deleted;
@OneToOne(cascade=CascadeType.ALL)
@PrimaryKeyJoinColumn
private Role role;
public Integer getId() {
return id;
}
......
}
我的用户界面
package sg.com.innovax.opscentralv5.table.service;
import ....;
import sg.com.innovax.opscentralv5.table.User;
public interface UserService {
public List<User> findAll();
......;
}
答案 0 :(得分:2)
解决的问题。 造成它的原因有两个。
从安全xml中删除<debug/>
https://jira.springsource.org/browse/SEC-1885
在spring-servlet.xml中放入org.springframework.web.servlet.view.InternalResourceViewResolver类(之前我放入应用程序上下文xml)。
现在:
我的web.xml
......
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
......
我的spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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.1.xsd">
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
答案 1 :(得分:0)
您没有在我的root-context.xml中定义UserService aUserService。您必须将其定义为
<beans:bean id="aUserService" class=" UserService implementation classname">
或
在UserService实现类中添加@Service注释。这样就可以了。
答案 2 :(得分:0)
根据您的初始设置,以下内容应该有效:
由于您在@Service("jpaUserService")
(http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/stereotype/Service.html)中指定了bean创建的名称,因此通过此名称引用从注释扫描创建的Bean的名称。所以你可以用这个名字来引用它。为此,请执行以下操作:
@Autowired
@Qualifier("jpaUserService"")
private UserService aUserService;
,无需使用getter和setter
答案 3 :(得分:0)
问题: 自动装配失败是因为Spring默认使用JDK-Dynamic代理创建代理(它创建一个实现目标类接口的代理)。另一方面,基于CGLIB的代理是目标类的子类。 请参阅:JDK动态代理和CGLib之间有什么区别? 要启用基于CGLIB的代理,请使用
注释其中一个@Configuration类@EnableAspectJAutoProxy(proxyTargetClass=true):
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class AppConfig
并添加: org.aspectj aspectjweaver 1.8.9
如有必要