我正在运行一个基于Spring安全性版本4.2,spring mvc 4.2版的Web应用程序。我想运行 customAuthenticationProvider 和 customAuthenticationSuccessHandler ,但是没有调用customAuthenticationProvider类,而且只有 authentication-failure-url
的pom.xml
<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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http pattern="/resources/css/**" security="none"/>
<http pattern="/resources/img/**" security="none"/>
<http pattern="/resources/js/**" security="none"/>
<http auto-config="false" use-expressions="true">
<!-- <intercept-url pattern="/onemoretime/*" access="hasRole('ROLE_ADMIN')"/>-->
<intercept-url pattern="/admin/*" access="permitAll"/>
<intercept-url pattern="/vendor/*" access="permitAll"/>
<form-login login-page="/login"
username-parameter="username"
password-parameter="password"
authentication-success-handler-ref="customAuthenticationSuccessHandler"
authentication-failure-url="/accessdenied"
/>
<!-- <logout logout-success-url="/login"/> -->
<csrf />
</http>
<authentication-manager alias="authenticationProvider">
<authentication-provider ref="myAuthenticationProvider"/>
</authentication-manager>
<!-- Bean implementing AuthenticationProvider of Spring Security -->
<beans:bean id="myAuthenticationProvider" class="com.opstree.vendorportal.authentication.CustomAuthenticationProvider"/>
<beans:bean id="customAuthenticationSuccessHandler" class="com.opstree.vendorportal.authentication.CustomAuthenticationSuccess"/>
</beans:beans>
应用的security.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/service.xml /WEB-INF/application-security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
的web.xml
<form action="${pageContext.request.contextPath}/login" method="post">
<table>
<tr>
<td>UserName</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password"> </td>
</tr>
<tr>
<td align="center" colspan="2">
<div style="color:red" class="servererror">
<c:if test="${not empty userobject}">
<b><c:out value="${userobject.message}"></c:out></b>
</c:if>
</div>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<input type="submit" value="Login">
</td>
</tr>
<tr>
<td align="center" colspan="2">
<b><a href="forgotpassword">ForgotPassword</a></b>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<b>Click here to <a href="registerVendor">Register</a></b>
</td>
</tr>
</table>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
loginpage.jsp
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserDBOperationsImpl userDAO;
private Logger logger = Logger.getLogger(getClass());
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
System.out.println("Spring Security: Entered");
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) authentication;
String username = authenticationToken.getName();
//String password = (String) authenticationToken.getCredentials();
UserBean userBean = null;
try {
userBean = userDAO.getUserDetails(username);
} catch (Exception e) {
logger.error(e.getCause().getMessage());
}
if(userBean == null){
throw new BadCredentialsException("Invalid Credentials");
}
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
Authentication auth = new UsernamePasswordAuthenticationToken(userBean, userBean.getPassword(), authorities);
System.out.println("Exit");
return auth;
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(getClass());
}
customAuthenticationProvider
public class CustomAuthenticationSuccess implements AuthenticationSuccessHandler {
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth)
throws IOException, ServletException {
System.out.println("Entered Authentication Successful Method");
boolean isUser = false;
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
String targetUrl = null;
for(GrantedAuthority currentAuth : authorities){
if(currentAuth.getAuthority().equalsIgnoreCase("ROLE_USER")){
isUser = true;
break;
}
else {
throw new IllegalStateException();
}
}
if(isUser){
targetUrl = "/vendor";
}
System.out.println("Entered Authentication Successful Method");
redirectStrategy.sendRedirect(request, response, targetUrl);
}
}
customAuthenticationSuccess
Public Class Demo
{
public Demo()
{
var connection = new HubConnection("http://localhost:47315/")
{
CookieContainer = new CookieContainer()
};
connection.CookieContainer.Add(GetAuthCookie("user1", "pass"));
chatHubProxy = connection.CreateHubProxy("servicesSatatuseHub");
connection.Start().Wait();
}
private static System.Net.Cookie GetAuthCookie(string user, string pass)
{
//var http = WebRequest.Create("http://localhost:47315/module/account/login.aspx") as HttpWebRequest;
var http = WebRequest.Create("http://localhost:47315//module/account/login.aspx") as HttpWebRequest;
http.AllowAutoRedirect = false;
http.Method = "POST";
http.ContentType = "application/x-www-form-urlencoded";
http.CookieContainer = new CookieContainer();
//var postData = "UserName=" + user + "&Password=" + pass + "";
var postData = "UserName=" + user + "&Password=" + pass + "";
byte[] dataBytes = System.Text.Encoding.UTF8.GetBytes(postData);
http.ContentLength = dataBytes.Length;
using (var postStream = http.GetRequestStream())
{
postStream.Write(dataBytes, 0, dataBytes.Length);
}
System.Net.Cookie authCookie;
using (var response = http.GetResponse() as HttpWebResponse)
{
authCookie = response.Cookies[FormsAuthentication.FormsCookieName];//authCookie = null
}
httpResponse.Close();
return cookie;
}
}
答案 0 :(得分:1)
我认为发生的情况是supports(Class<?> authentication)
中的AuthenticationProvider
方法未正确实施。
您正在检查已根据Authentication
CustomAuthenticationProvider
方法收到的getClass()
课程,因此总是会返回false,AuthenticationManager
将无法将您的提供者视为合适的已收到UsernamePasswordAuthenticationToken
的提供商。
您可以在github中检查org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider代码,您可以在UsernamePasswordAuthenticationToken
支持提供商中看到此方法的正确实现应该是这样的:
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class
.isAssignableFrom(authentication));
}
我猜实际发生的事情是AuthenticationManager
无法找到UsernamePasswordAuthenticationToken
支持提供商,因此无法执行身份验证,未经授权的Authentication
将转到UsernamePasswordAuthenticationFilter
最终无关,但重定向到authentication-failure-url
。
使用AuthenticationSuccessHandler
时也要小心,如果第一个GranthedAuthorities
评估的IllegalStateException
不是GranthedAuthority
,那么ROLE_USER
检查的方式可能会以 for(GrantedAuthority currentAuth : authorities){
if(currentAuth.getAuthority().equalsIgnoreCase("ROLE_USER")){
isUser = true;
break;
}
else {
throw new IllegalStateException();
}
}
结尾一个:
Perl