Spring перенаправление безопасности на основе роли
У меня есть следующий файл spring -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: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/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http auto-config="true">
<intercept-url pattern="/Freelancer/**" access="ROLE_FREELANCE" />
<intercept-url pattern="/Client/**" access="ROLE_CLIENT" />
<intercept-url pattern="/Agency/**" access="ROLE_AGENCY" />
<intercept-url pattern="/Manager/**" access="ROLE_MANAGER" />
<intercept-url pattern="/User/**" access="ROLE_USER" />
<form-login default-target-url="/${role}" login-page="/login.jsp" />
<logout logout-url="/logout" logout-success-url="/" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select user_name,password, enabled from Users where user_name=?"
authorities-by-username-query="select u.user_name, u.role from Users u where u.user_name =?"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
что я хочу, я хочу перенаправить пользователя в свою рабочую область, например, если клиент будет подключен, то он будет перенаправлен на /Client/index.jsp, если вход в систему Агентства будет перенаправлен в /Agency/index.jsp.
есть ли способ доступа к роли раньше, он будет перенаправлен на свое рабочее пространство в файле spring -security.xml.
<form-login default-target-url="/${role}" login-page="/login.jsp" />
У меня есть синтаксис структуры каталогов для роли.
имеют любую идею.
Ответы
Ответ 1
Напишите контроллер spring, который будет показывать разные страницы, которые будут показаны на основе роли пользователя. Запишите класс обработчика успешности аутентификации и напишите код, чтобы решить, где перенаправить на основе ролей.
Прежде всего нужно изменить тег <form-login />
.
<form-login login-page="/landing" authentication-success-handler-ref="authSuccessHandler" />
<beans:bean id="authSuccessHandler" class="com.package.AuthSuccessHandler" />
Удалите атрибут default-target-url
. Пусть auth-обработчик решает, где перенаправить пользователя.
Класс обработчика успеха Auth будет выглядеть следующим образом:
public class AuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Override
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
// Get the role of logged in user
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String role = auth.getAuthorities().toString();
String targetUrl = "";
if(role.contains("client")) {
targetUrl = "/client/index";
} else if(role.contains("agency")) {
targetUrl = "/agency/index"
}
return targetUrl;
}
}
Это пример кода. Измените его в соответствии с вашими требованиями.
Ответ 2
Лучше проверять роли с равными в предоставленных полномочиях, содержит может сбой, если несколько роли существуют с одной и той же частью.
Добавьте обработчик успеха проверки подлинности в конфигурацию входа в форму, как показано ниже:
<http auto-config="true">
<intercept-url pattern="/Freelancer/**" access="ROLE_FREELANCE" />
<intercept-url pattern="/Client/**" access="ROLE_CLIENT" />
<intercept-url pattern="/Agency/**" access="ROLE_AGENCY" />
<intercept-url pattern="/Manager/**" access="ROLE_MANAGER" />
<intercept-url pattern="/User/**" access="ROLE_USER" />
<form-login login-page='/login.html'
authentication-failure-url="/login.html?error=true"
authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
<logout logout-url="/logout" logout-success-url="/" />
</http>
И обработчик успеха выглядит следующим образом:
public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
protected Log logger = LogFactory.getLog(this.getClass());
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
handle(request, response, authentication);
clearAuthenticationAttributes(request);
}
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
String targetUrl = determineTargetUrl(authentication);
if (response.isCommitted()) {
logger.debug(
"Response has already been committed. Unable to redirect to "
+ targetUrl);
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
protected String determineTargetUrl(Authentication authentication) {
boolean isUser = false;
boolean isFreelance = false;
boolean isClient = false;
boolean isAgency = false;
boolean isManager = false;
Collection<? extends GrantedAuthority> authorities
= authentication.getAuthorities();
for (GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals("ROLE_FREELANCE")) {
isFreelance = true;
break;
} else if (grantedAuthority.getAuthority().equals("ROLE_CLIENT")) {
isClient = true;
break;
} else if (grantedAuthority.getAuthority().equals("ROLE_AGENCY")) {
isAgency = true;
break;
} else if (grantedAuthority.getAuthority().equals("ROLE_MANAGER")) {
isManager = true;
break;
} else if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
isUser = true;
break;
}
}
if (isFreelance) {
return "freelance/homepage.html";
} else if (isClient) {
return "client/homepage.html";
} else if (isAgency) {
return "agency/homepage.html";
} else if (isManager) {
return "manager/homepage.html";
} else if (isUser) {
return "user/homepage.html";
} else {
throw new IllegalStateException();
}
}
protected void clearAuthenticationAttributes(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
Ответ 3
Вы можете использовать решение на основе аннотаций, используя специальный обработчик успеха, подобный этому:
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
@Component
public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
String targetUrl = determineTargetUrl(authentication);
if (response.isCommitted()) {
System.out.println("Can't redirect");
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
/*
* This method extracts the roles of currently logged-in user and returns
* appropriate URL according to his/her role.
*/
protected String determineTargetUrl(Authentication authentication) {
String url = "";
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
List<String> roles = new ArrayList<String>();
for (GrantedAuthority a : authorities) {
roles.add(a.getAuthority());
}
if (isDba(roles)) {
url = "/db";
} else if (isAdmin(roles)) {
url = "/admin";
} else if (isUser(roles)) {
url = "/home";
} else {
url = "/accessDenied";
}
return url;
}
private boolean isUser(List<String> roles) {
if (roles.contains("ROLE_USER")) {
return true;
}
return false;
}
private boolean isAdmin(List<String> roles) {
if (roles.contains("ROLE_ADMIN")) {
return true;
}
return false;
}
private boolean isDba(List<String> roles) {
if (roles.contains("ROLE_DBA")) {
return true;
}
return false;
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
И настройка безопасности как:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
CustomSuccessHandler customSuccessHandler;
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN");
auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/home").access("hasRole('USER')")
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.and().formLogin().loginPage("/login").successHandler(customSuccessHandler)
.usernameParameter("ssoId").passwordParameter("password")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/Access_Denied");
}
}