Привет всем я хочу сделать автоматический вход после успешной регистрации в spring имея в виду: У меня есть защищенная страница, которая требует входа в систему для доступа к ним и я хочу, чтобы после регистрации пропустить страницу входа и сделать автоматический вход, чтобы пользователь мог видеть эту защищенную страницу, получил меня? Я использую spring 3.0, spring security 3.0.2 как это сделать?
Автоматический вход после успешной регистрации
Ответ 1
Это можно сделать с помощью безопасности spring следующим образом (semi-psuedocode):
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
@Controller
public class SignupController
{
@Autowired
RequestCache requestCache;
@Autowired
protected AuthenticationManager authenticationManager;
@RequestMapping(value = "/account/signup/", method = RequestMethod.POST)
public String createNewUser(@ModelAttribute("user") User user, BindingResult result, HttpServletRequest request, HttpServletResponse response) {
//After successfully Creating user
authenticateUserAndSetSession(user, request);
return "redirect:/home/";
}
private void authenticateUserAndSetSession(User user, HttpServletRequest request) {
String username = user.getUsername();
String password = user.getPassword();
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
// generate session if one doesn't exist
request.getSession();
token.setDetails(new WebAuthenticationDetails(request));
Authentication authenticatedUser = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
}
}
Обновление: содержать только то, как создать сеанс после регистрации
Ответ 2
В Servlet 3+ вы можете просто сделать request.login("username","password")
и в случае успеха перенаправить на любую страницу, которую вы хотите. Вы можете сделать то же самое для автоматического выхода из системы.
Вот ссылка на раздел документации, в котором говорится об этом: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#servletapi-3
Ответ 3
Просто комментарий к первому ответу о том, как сделать autwire authenticationManager.
Вам нужно установить псевдоним, когда вы объявляете диспетчер аутентификации в файле requestion-servlet.xml или applicationContext-security.xml:
<authentication-manager alias="authenticationManager>
<authentication-provider>
<user-service>
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobspassword" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
Кроме того, при аутентификации он может выдать исключение аутентификации, поэтому вам нужно его поймать:
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword());
request.getSession();
token.setDetails(new WebAuthenticationDetails(request));
try{
Authentication auth = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(auth);
} catch(Exception e){
e.printStackTrace();
}
return "redirect:xxxx.htm";
Ответ 4
- Настройте web.xml, чтобы позволить Spring безопасности обрабатывать данные для URL-адреса для входа в систему.
- Запрос на регистрацию ручек, например. создать пользователя, обновить ACL и т.д.
- Переслать его с именем пользователя и паролем для URL-адреса входа в систему для аутентификации.
- Получите преимущества цельной цепи Spring Защитный фильтр, например. защита фиксации сеанса.
Так как форварды являются внутренними, он будет отображаться для пользователя так, как если бы они были зарегистрированы и вошли в систему во время одного и того же запроса.
Если ваша регистрационная форма не содержит правильных имен параметров имени пользователя и пароля, отправьте измененную версию запроса (используя HttpServletRequestWrapper
) в конечную точку доступа Spring.
Чтобы это сработало, вам нужно будет изменить ваш web.xml, чтобы маркер цепи безопасности Spring перешел вперед для login-processing-url
. Например:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!-- Handle authentication for normal requests. -->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Handle authentication via forwarding for internal/automatic authentication. -->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/login/auth</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Ответ 5
Использование SecurityContextHolder.getContext(). setAuthentication (Authentication) выполняет задание, но оно обходит цепочку фильтров безопасности spring, которая откроет угрозу безопасности.
Например, скажем, в моем случае, когда пользователь reset пароль, я хотел, чтобы он забрал на приборную панель без входа снова. Когда я использовал вышеупомянутый подход, он выводит меня на панель мониторинга, но он обходит мой фильтр concurrency, который я применил, чтобы избежать параллельного входа. Вот фрагмент кода, который выполняет задание:
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(empId, password);
Authentication auth = authenticationManager.authenticate(authToken);
SecurityContextHolder.getContext().setAuthentication(auth);
Использовать атрибут login-processing-url вместе с простым изменением в web.xml
безопасности XML
<form-login login-page="/login"
always-use-default-target="false"
default-target-url="/target-url"
authentication-failure-url="/login?error"
login-processing-url="/submitLogin"/>
web.xml
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/submitLogin</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Добавляя этот фрагмент кода в web.xml, на самом деле выполняется перенаправление вашего явного запроса на пересылку, который вы будете делать во время автоматического входа в систему и передачи его в цепочку фильтров безопасности spring.
Надеюсь, что это поможет
Ответ 6
Spring Ответ на обезьяну отлично работает, но я обнаружил сложную проблему при ее реализации.
Моя проблема состояла в том, что я установил на странице регистрации "нет безопасности", например:
<http pattern="/register/**" security="none"/>
Я думаю, что это не приводит к инициализации SecurityContext и, следовательно, после пользовательских регистров, аутентификация внутри сервера не может быть сохранена.
Мне пришлось изменить обход страницы регистрации, установив его в IS_AUTHENTICATED_ANONYMOUSLY
<http authentication-manager-ref="authMgr">
<intercept-url pattern="/register/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
...
</http>
Ответ 7
Это ответ на предыдущий вопрос В контроллере:
@RequestMapping(value = "/registerHere", method = RequestMethod.POST)
public ModelAndView registerUser(@ModelAttribute("user") Users user, BindingResult result,
HttpServletRequest request, HttpServletResponse response) {
System.out.println("register 3");
ModelAndView mv = new ModelAndView("/home");
mv.addObject("homePagee", "true");
String uname = user.getUsername();
if (userDAO.getUserByName(uname) == null) {
String passwordFromForm = user.getPassword();
userDAO.saveOrUpdate(user);
try {
authenticateUserAndSetSession(user, passwordFromForm, request);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("register 4");
log.debug("Ending of the method registerUser");
return mv;
}
Далее описанный выше метод в контроллере определяется как:
`private void authenticateUserAndSetSession(Users user, String passwor`dFromForm, HttpServletRequest request){
String username = user.getUsername();
System.out.println("username: " + username + " password: " + passwordFromForm);
UserDetails userDetails = userDetailsService.loadUserByUsername(user.getUsername());
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, passwordFromForm, userDetails.getAuthorities());
request.getSession();
System.out.println("Line Authentication 1");
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetails(request));
System.out.println("Line Authentication 2");
Authentication authenticatedUser = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
System.out.println("Line Authentication 3");
if (usernamePasswordAuthenticationToken.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
System.out.println("Line Authentication 4");
}
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());// creates context for that session.
System.out.println("Line Authentication 5");
session.setAttribute("username", user.getUsername());
System.out.println("Line Authentication 6");
session.setAttribute("authorities", usernamePasswordAuthenticationToken.getAuthorities());
System.out.println("username: " + user.getUsername() + "password: " + user.getPassword()+"authorities: "+ usernamePasswordAuthenticationToken.getAuthorities());
user = userDAO.validate(user.getUsername(), user.getPassword());
log.debug("You are successfully register");
}
Другие ответы не предлагали помещать его в try/catch, поэтому никто не понимает, почему логика не работает, поскольку работает код... и ничего не происходит ни на ошибке, ни на консоли. Поэтому, если вы не ставите его в try catch, вы не получите исключение из-за плохих учетных данных.
Ответ 8
Это альтернатива интеграции сервлета 3+. Если вы используете учетную запись Spring Security form, вы можете просто делегировать ее на свою страницу входа в систему. Например:
@PostMapping("/signup")
public String signUp(User user) {
// encode the password and save the user
return "forward:/login";
}
Предполагая, что у вас есть поля username
и password
в вашей форме, тогда 'forward' отправит эти параметры, а Spring Security будет использовать те, которые будут аутентифицироваться.
Преимущество, которое я нашел с этим подходом, состоит в том, что вы не дублируете свой formLogin
defaultSuccessUrl
(пример настройки безопасности ниже). Он также очищает ваш контроллер, не требуя параметра HttpServletRequest
.
@Override
public void configure(HttpSecurity http) {
http.authorizeRequests()
.antMatchers("/", "/signup").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home", true)
.permitAll();
}
Ответ 9
Я не уверен, если вы просите об этом, но в вашей конфигурации безопасности Spring вы можете добавить тег "запомнить-меня". Это будет управлять файлом cookie в вашем клиенте, поэтому в следующий раз (если файл cookie не истек), вы автоматически регистрируетесь.
<http>
...
<remember-me />
</http>