我想有三个值创建登录页面:春季安全自定义登录
- 用户名
- 密码
- 公司名称
我的应用程序支持不同的公司,和一个单用户可能是多个公司的用户,因此,在登录页面中,作为登录的一部分,用户必须选择要登录的公司。
这是我目前正在使用:
- 的Java 8
- 春天4.0.3.RELEASE(我用个XML文件)
- 春季安全4.0.3.RELEASE
- 休眠4.2.21.Final
- Thymeleaf 2.1.4.RELEASE
这是我的弹簧security.xml文件
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="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-4.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<b:bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<b:constructor-arg value="256"/>
<b:property name="iterations" value="8224"/>
</b:bean>
<!-- Define the User property to use for salting password encoding -->
<b:bean id="saltSource"
class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<b:property name="userPropertyToUse" value="userSalt"/>
</b:bean>
<b:bean id="userCompanyAuthenticationProvider"
class="com.mycompany.security.authentication.UserCompanyAuthenticationProvider">
</b:bean>
<!--Authentication provider to use for Spring Security-->
<!--<b:bean id="daoAuthenticationProvider" -->
<!--class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">-->
<!--<!– userDetailsService is annotated at com.mycompany.security.userdetails.UserDetailsServiceImpl –>-->
<!--<b:property name="userDetailsService" ref="userDetailsService"/>-->
<!--<b:property name="passwordEncoder" ref="passwordEncoder"/>-->
<!--<b:property name="saltSource" ref="saltSource"/>-->
<!--</b:bean>-->
<b:bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<!--<authentication-manager alias="authenticationManager">-->
<!--<authentication-provider ref="daoAuthenticationProvider" />-->
<!--</authentication-manager>-->
<!-- Turn off Spring Security for the following URL/patterns -->
<http pattern="/_ui/**" security="none"/>
<http pattern="/resources/**" security="none"/>
<!-- Configure the HTTP realm/security settings and enable SpEL expressions -->
<http use-expressions="true" auto-config="false" entry-point-ref="loginEntryPoint">
<custom-filter ref="userCompanyFormLoginFilter"
position="FORM_LOGIN_FILTER"/>
<csrf disabled="true"/>
<!-- Enable remember me cookie functionality -->
<!--<remember-me key="myappRememberMe"-->
<!--token-validity-seconds="2419200"/>-->
<intercept-url pattern="/favicon.ico" access="permitAll"/>
<intercept-url pattern="/login" access="permitAll"/>
<intercept-url pattern="/logout" access="permitAll"/>
<intercept-url pattern="/auth/**" access="permitAll"/>
<intercept-url pattern="/signup/**" access="permitAll"/>
<intercept-url pattern="/static/**" access="permitAll"/>
<intercept-url pattern="/resources/**" access="permitAll"/>
<intercept-url pattern="/_ui/**" access="permitAll"/>
<intercept-url pattern="/user" access="hasRole('ROLE_USER')"/>
<intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/**" access="isAuthenticated()"/>
<access-denied-handler ref="customAccessDeniedHandler"/>
<!-- Login Page -->
<!--<form-login login-page="/login" default-target-url="/"-->
<!--login-processing-url="/static/j_spring_security_check"-->
<!--authentication-failure-url="/login?error=true" />-->
<!-- URL for logging out and specific cookies to delete when doing so. -->
<!--<logout logout-url="/logout" delete-cookies="JSESSIONID"/>-->
<!-- delete-cookies="JSESSIONID, SPRING_SECURITY_REMEMBER_ME_COOKIE" -->
<session-management>
<concurrency-control max-sessions="1"
error-if-maximum-exceeded="false"/>
</session-management>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="userCompanyAuthenticationProvider"/>
</authentication-manager>
<b:bean id="userCompanyFormLoginFilter" class="com.mycompany.security.filter.UserCompanyAuthenticationFilter">
<b:property name="filterProcessesUrl" value="/login/form"/>
<b:property name="authenticationManager" ref="authenticationManager"/>
<b:property name="usernameParameter" value="username"/>
<b:property name="passwordParameter" value="password"/>
</b:bean>
<b:bean id="loginEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<b:constructor-arg value="/login"/>
</b:bean>
<b:bean id="customAccessDeniedHandler" class="com.mycompany.security.AccessDeniedHandlerApp"/>
</b:beans>
这是我UserCompanyAuthenticationFilter
package com.mycompany.security.filter;
import com.mycompany.security.authentication.UserCompanyAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UserCompanyAuthenticationFilter extends UsernamePasswordAuthenticationFilter
{
@Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException
{
if (!request.getMethod().equals("POST"))
{
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
String company = request.getParameter("company");
UserCompanyAuthenticationToken authRequest = new UserCompanyAuthenticationToken(username, password, company);
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
}
这是我UserCompanyAuthenticationProvider:
package com.mycompany.security.authentication;
import com.mycompany.entity.User;
import com.mycompany.myapp.dao.service.CompanyService;
import com.mycompany.myapp.dao.service.LoginService;
import com.mycompany.security.RoleEnumerator;
import com.mycompany.security.UnknownRoleException;
import org.apache.log4j.Logger;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
public class UserCompanyAuthenticationProvider implements AuthenticationProvider
{
private LoginService loginService;
private CompanyService companyService;
private static final Logger LOGGER = Logger.getLogger(UserCompanyAuthenticationProvider.class);
@Override public Authentication authenticate(Authentication authentication) throws AuthenticationException
{
UserCompanyAuthenticationToken token = (UserCompanyAuthenticationToken) authentication;
String username = token.getName();
String company = token.getCompany();
User user = null;
if (username != null)
{
user = loginService.getByUsername(username, companyService.get(Long.parseLong(company)));
}
if (user == null)
{
throw new BadCredentialsException("Invalid username - password");
}
String password = user.getPasswordHash();
if (!loginService.isValidUsernameAndPasswordHashCombination(username, password))
{
throw new BadCredentialsException("Invalid username - password");
}
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
try
{
RoleEnumerator.getApplicableRoles(user)
.forEach(role -> authorities.add(new SimpleGrantedAuthority(role.toString())));
}
catch (UnknownRoleException rex)
{
LOGGER.error(rex.getMessage(), rex);
}
return new UserCompanyAuthenticationToken(user.getUsername(), password, authorities, company);
}
@Override public boolean supports(Class<?> authentication)
{
return UserCompanyAuthenticationToken.class.equals(authentication);
}
@Inject public void setLoginService(LoginService loginService)
{
this.loginService = loginService;
}
@Inject public void setCompanyService(CompanyService companyService)
{
this.companyService = companyService;
}
}
这是我UserCompanyAuthenticationToken
package com.mycompany.security.authentication;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
public class UserCompanyAuthenticationToken extends UsernamePasswordAuthenticationToken
{
private final String company;
public UserCompanyAuthenticationToken(String principal, String credentials, String company)
{
super(principal, credentials);
this.company = company;
}
public UserCompanyAuthenticationToken(String principal, String credentials,
Collection<? extends GrantedAuthority> authorities, String company)
{
super(principal, credentials, authorities);
this.company = company;
}
public String getCompany()
{
return company;
}
}
到目前为止,我在httprequest(用户名,密码和公司)中发送了三个值,并且所有内容都正常工作。
但是,密码没有编码,我想要做的就是编码密码并发送saltSource以便比较密码和salt。
有没有人有关于如何做到这一点的例子?或者有没有人有任何建议或指示如何做到这一点?
在此先感谢
“_salt theSource为了比较密码和salt_”。现在怎么办?使用BCrypt?否则,你使用哪种算法? –