我正在使用春季安全3 当我输入错误的数据时,用户被重定向到login-failure-link 但是spring security不会调用loadUserByUsername方法吗? 那么身份验证是如何发生的并且spring知道凭据是错误的? 或者我的配置有问题,请指导。
登录页面:
<form action="/myapp/j_spring_security_check">
<h:graphicImage id="graphicImage1" style="height: 322px; left: 0px; top: 0px; position: absolute" url="/resources/images/LoginImage.jpg" width="560"/>
<h:outputLabel for="j_username" id="outputLabel1" style="left: 48px; top: 120px; position: absolute" value="Username:"/>
<h:outputLabel for="j_password" id="outputLabel2" style="left: 48px; top: 168px; position: absolute" value="Password:"/>
<h:inputText binding="#{login.username}" id="j_username" required="true"
style="left: 142px; top: 118px; position: absolute; width: 237px" />
<h:inputSecret binding="#{login.password}" id="j_password" required="true" style="left: 142px; top: 166px; position: absolute; width: 237px"/>
<h:commandButton id="loginBtn" style="left: 144px; top: 240px; position: absolute" value="Login"/>
<h:commandButton action="#{login.reset}" id="resetBtn" style="position: absolute; left: 360px; top: 240px" value="Reset"/>
<h:outputText id="errorMessage" style="left:0px;top:300px;position:absolute"/>
<h:message errorClass="errorMessage" for="j_username" fatalClass="fatalMessage" id="messages1" infoClass="infoMessage" showSummary="false"
style="height: 43px; left: 24px; top: 288px; position: absolute; width: 523px;color:red;" warnClass="warnMessage"/>
</form>
security.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-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.4.xsd">
<global-method-security pre-post-annotations="enabled" />
<!-- key configuration here is an entry point to be used by security intercepts -->
<http use-expressions="true" auto-config="false">
<session-management session-fixation-protection="none"/>
<remember-me token-validity-seconds="1209600"/>
<!-- Exclude the login page from the security check -->
<intercept-url pattern="/faces/login.xhtml" access="permitAll"/>
<!-- All pages requires authentication (not anonymous user) -->
<intercept-url pattern="/faces/**" access="isAuthenticated()" />
<intercept-url pattern="/faces/javax.faces.resource/**" filters="none" />
<intercept-url pattern="/faces/xmlhttp/**" filters="none" />
<intercept-url pattern="/faces/resources/**" filters="none" />
<intercept-url pattern="/faces/j_spring_security_check/**" filters="none" />
<intercept-url pattern="/scripts/**" filters="none" />
<intercept-url pattern="/images/**" filters="none" />
<intercept-url pattern="/css/**" filters="none" />
<!-- Returns true if the user is not anonymous -->
<access-denied-handler error-page="/error"/>
<form-login default-target-url="/users"
always-use-default-target="true"
login-processing-url="/j_spring_security_check"
login-page="/faces/login.xhtml"
authentication-failure-url="/faces/login.xhtml?login_error=1"
/>
<logout logout-url="/logout" logout-success-url="/login" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsServiceImpl">
</authentication-provider>
</authentication-manager>
</beans:beans>
3- UserDetailsService:
@Service("userDetailsServiceImpl")
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
System.out.println("########## LOADING USER ##################");
User user = userDao.findUserByEmail(username);
return new org.springframework.security.core.userdetails.User(
user.getEmail(), user.getPassword(), true, true, true, true,
setUserAuthorities(user.getAuthorities()));
}
public Collection<GrantedAuthority> setUserAuthorities(List<Authority> auths) {
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
for (Authority auth : auths)
grantedAuthorities.add(new GrantedAuthorityImpl(auth.getName()));
return grantedAuthorities;
}
}
答案 0 :(得分:3)
You remember that I told that spring security adds a lot of filters?其中一个过滤器负责检查j_spring_security_check
的请求是否已通知验证管理器。
但你没有那个过滤器。
如果没有理由不这样做,请启用自动配置:
<http use-expressions="true" auto-config="true">
并为/j_spring_security_check
<intercept-url pattern="/j_spring_security_check" access="permitAll"/>
答案 1 :(得分:1)
因为我有这个
将弹簧安全性从3.2.8升级到4.0.2后出现了一些其他问题 即使已经存在,我也会留下对我的情况的描述 接受了正确答案。未调用loadUserByUsername
所以昨天我决定提到安全升级。 首先,与安全性4.0.2一样,默认情况下启用csrf保护, 我需要在我的security-context.xml中关闭它:
<http>
.
.
.
<csrf disabled="true"/>
</http>
在项目的当前阶段,csrf保护并未包含在角度UI中。 这一刻导致上下文初始化错误。
之后我看到我无法登录该应用程序。 我正在为默认的 j_spring_security_check URL进行POST。 但Spring Security 4.0.2使用另一个: Spring Security Reference
login-processing-url 映射到filterProcessesUrl属性 UsernamePasswordAuthenticationFilter。默认值为&#34; / login&#34;。
默认的logout-url也发生了变化: Spring Security Reference
logout-url 将导致注销的URL(即将由过滤器处理的URL)。默认为&#34; / logout&#34;。
所以我对mine-context.xml进行了更改,登录/注销返回到了正确的行为。
之后我注意到我的@PreAuthorize注释无法正常工作。 我使用角色名称定义为常量:
@PreAuthorize("hasRole(T(org...UserService).ADMIN_ROLE_NAME)"
+ " or hasRole(T(org...UserService).OWNER_ROLE_NAME)")
角色名称是:
public final static String ADMIN_ROLE_NAME = "admin";
public final static String USER_ROLE_NAME = "plain_user";
public final static String OWNER_ROLE_NAME = "company_owner";
如你所见,他们没有包含&#39; ROLE _&#39;字首。 据我所知,安全4.0.2无法使用这些名称。 可能是因为: Spring Security Reference
现在您可以选择省略ROLE_前缀。我们这样做是为了删除 复制。具体来说,因为表达式已经有了 将值定义为角色,如果是,则自动添加前缀 不在那里。
我将角色名称更改为:
public final static String ADMIN_ROLE_NAME = "ROLE_ADMIN";
public final static String USER_ROLE_NAME = "ROLE_USER";
public final static String OWNER_ROLE_NAME = "ROLE_OWNER";
并且安全性恢复了正常的行为。
P.S。 (根据拉尔夫的回答)
并为/ j_spring_security_check添加拦截器
我没有拦截3.2.8默认的login-processing-url。 我没有拦截器4.0.2默认login-processing-url。 在我的security-context.xml中有登录页面本身的拦截器:
<intercept-url pattern="/authorize" access="permitAll" />
只返回login.html。
答案 2 :(得分:0)
我也面临着同样的问题。然后我发现问题是我正在查看已在运行的不同端口上的同一服务器。验证端口号。