我正在尝试使用spring security创建登录身份验证。我收到了404登录url /knowledgeBase/j_spring_security_check
未找到的错误。我已经在安全xml中正确定义了我的自定义过滤器和我的URL。我还在web xml文件中添加了一个安全过滤器。我通过序列化表单数据通过ajax请求调用此url。我已经成功地在另一个项目中使用此代码,但现在我收到此错误。可能是什么原因?
这是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/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Disabled Security for Static Resources -->
<global-method-security pre-post-annotations="enabled" secured-annotations="enabled"/>
<http pattern="/static/**" security="none"/>
<beans:bean id="shaPasswordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="256"/>
</beans:bean>
<beans:bean id="userService" class="com.gsu.knowledgebase.service.UserService"/>
<!-- Ajax Aware Handler -->
<beans:bean id="authEntryPoint"
class="com.gsu.knowledgebase.spring.AjaxAwareLoginUrlAuthenticationEntryPoint"
scope="singleton">
<beans:constructor-arg name="loginFormUrl" value="/knowledge-base"/>
</beans:bean>
<http authentication-manager-ref="authenticationManager" entry-point-ref="authEntryPoint"
pattern="/knowledge-base/**"
use-expressions="true" disable-url-rewriting="true">
<custom-filter position="BASIC_AUTH_FILTER" ref="loginFilter"/>
<logout logout-success-url="/knowledge-base" invalidate-session="true" delete-cookies="JSESSIONID"
logout-url="/knowledgeBase/j_spring_security_logout"/>
<intercept-url pattern="/knowledge-base/" access="permitAll"/>
<intercept-url pattern="/knowledge-base/memory"
access="hasRole('ADMIN') || hasRole('MODERATOR') || hasRole('USER')"/>
<access-denied-handler error-page="/knowledge-base/error/403"/>
<session-management session-authentication-error-url="/knowledge-base/error/sessionExpired"/>
</http>
<!-- ************************** -->
<authentication-manager id="authenticationManager">
<authentication-provider user-service-ref="userService">
<password-encoder ref="shaPasswordEncoder"/>
</authentication-provider>
</authentication-manager>
<beans:bean id="loginFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="filterProcessesUrl" value="/knowledgeBase/j_spring_security_check"/>
<beans:property name="authenticationSuccessHandler">
<beans:bean class="com.gsu.knowledgebase.spring.AuthenticationSuccessHandler"/>
</beans:property>
<beans:property name="authenticationFailureHandler">
<beans:bean class="com.gsu.knowledgebase.spring.AuthenticationFailureHandler"/>
</beans:property>
</beans:bean>
<!-- ************************** -->
</beans:beans>
这是web.xml文件:
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring Web MVC Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/applicationContext.xml,
/WEB-INF/spring/security.xml
</param-value>
</context-param>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>
<servlet>
<servlet-name>main</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>knowledge-base</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlets/knowledge-base-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/visual/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>knowledge-base</servlet-name>
<url-pattern>/knowledge-base/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
这是我的登录表单:
<form id="login-form">
<div class="form-group">
<label>Username</label>
<input type="text" class="form-control" name="j_username" ng-model="username"
placeholder="Your username">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="j_password" class="form-control" ng-model="password"
placeholder="Password">
</div>
<div class="form-check">
<!--<input type="checkbox" class="form-check-input" id="exampleCheck1">-->
<!--<label class="form-check-label">Check me out</label>-->
</div>
<span class="validation-message" style="display:none;">{{validationMessage}}</span>
<span class="success-message" style="display:none;">{{successMessage}}</span>
<input type="button" class="btn btn-default blue" value="Log in"
ng-click="login()">
</form>
这就是我通过ajax调用j_spring_security_check网址的方式:
$.ajax({
type: "POST",
url: 'knowledgeBase/j_spring_security_check',
data: jQuery("#login-form").serialize(), // serializes the form's elements.
success: function (data) {
window.location = "/knowledge-base/memory";
},
error: function (data, textStatus, jqXHR) {
if (data.status == 410) {
} else if (data.status == 409) {
} else if (data.status == 406) {
} else {
}
$scope.$digest();
printError(textStatus);
}
});
但我收到404未找到错误。
更新:
解决这个问题后,我的UserService出现问题。它无法识别其中定义的自动连接依赖项。我尝试直接在变量和构造函数上使用Autowired注释。 knowledgbaseDao
在loadUserByUsername
中无效。在启动时,此类的构造函数被调用3次。每个创建不同的对象。第一个是使用默认的空构造函数创建的。其他两个是使用自动装配的构造函数创建的,并为knowledgebaseDao
指定正确的类。当从登录页面调用userservice时,它使用第一个UserService类并抛出空指针异常。这是我的代码:
@Component("userService")
public class UserService implements UserDetailsService {
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
private KnowledgeBaseDao knowledgeBaseDao;
public UserService(){
System.out.println();
}
@Autowired
public UserService(KnowledgeBaseDao knowledgeBaseDao) {
this.knowledgeBaseDao = knowledgeBaseDao;
}
public UserDetails loadUserByUsername(String login) throws AuthenticationException {
logger.info("UserDetails Database Service : " + login);
// check user exists in database
User user = knowledgeBaseDao.findUserByEmail(login);
if (user == null) {
logger.warn("User({}) does not exist in system", login);
throw new UsernameNotFoundException("There is no user with this username.");
}
boolean containsLoginRole = checkLoginRole(user);
if (!containsLoginRole) {
throw new UsernameNotFoundException("Access denied.");
}
if ((user.getStatus() == null || user.getStatus() == 0)) {
throw new UsernameNotFoundException("User is not confirmed");
}
//boolean enabled = user.getStatus() == AccountStatus.ACTIVE;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
if (user.getLoginTryCount() != null && user.getLoginTryCount() >= 3) {
accountNonLocked = false;
}
return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), true, accountNonExpired,
credentialsNonExpired, accountNonLocked, this.getAuthorities(user.getRoleId()));
}
public Collection<? extends GrantedAuthority> getAuthorities(Collection<Role> roleList) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (Role role : roleList) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
public Collection<? extends GrantedAuthority> getAuthorities(Long roleId) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority(Constants.ROLE_NAME(roleId.intValue())));
return authorities;
}
private boolean checkLoginRole(User user) {
if (user.getRoleId() == 0) {
return false;
}
if (user.getRoleId() == Constants.ROLE_ADMIN
|| user.getRoleId() == Constants.ROLE_MODERATOR
|| user.getRoleId() == Constants.ROLE_USER) {
return true;
} else {
return false;
}
}
}
你确定/ knowledgeBase是root servlet上下文url吗?我认为它是知识库..所以在这种情况下,正确的url make登录请求应该是/ knowledge-base / knowledgeBase / j_spring_security_check尝试通过邮递员发帖子