[SPRING] 성공적인 등록 후 자동 로그인
SPRING성공적인 등록 후 자동 로그인
모두 안녕 스프링 등록 성공 후 자동 로그인을하고 싶습니다. 의미: 나는 그들을 액세스하기 위해 로그인해야하는 보호 된 페이지가 있습니다. 그리고 나는 로그인 페이지를 건너 뛰고 자동 로그인을하여 사용자가 보호 된 페이지를 볼 수있게하고 싶습니다. 나는 봄 3.0, 봄 보안 3.0.2를 사용하고있다. 그렇게하는 방법?
해결법
-
==============================
1.이것은 다음과 같은 방식으로 봄 보안을 사용하여 수행 할 수 있습니다 (준 의사 코드).
이것은 다음과 같은 방식으로 봄 보안을 사용하여 수행 할 수 있습니다 (준 의사 코드).
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")을 수행하고 성공할 경우 원하는 페이지로 리디렉션 할 수 있습니다. 자동 로그 아웃에 대해서도 동일한 작업을 수행 할 수 있습니다.
Servlet 3+에서는 단순히 request.login ( "username", "password")을 수행하고 성공할 경우 원하는 페이지로 리디렉션 할 수 있습니다. 자동 로그 아웃에 대해서도 동일한 작업을 수행 할 수 있습니다.
다음은이 설명서에 대한 링크입니다. http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#servletapi-3
-
==============================
3.authenticationManager를 autowire하는 방법에 대한 첫 번째 회신에 대한 의견.
authenticationManager를 autowire하는 방법에 대한 첫 번째 회신에 대한 의견.
application-servlet.xml 또는 applicationContext-security.xml 파일에서 authentication-manager를 선언 할 때 별칭을 설정해야합니다.
<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>
또한 인증 할 때 AuthenticationException을 throw 할 수 있으므로 catch해야합니다.
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.전달은 내부이므로 사용자가 동일한 요청 중에 등록되고 로그인 된 것처럼 보입니다.
전달은 내부이므로 사용자가 동일한 요청 중에 등록되고 로그인 된 것처럼 보입니다.
등록 양식에 올바른 사용자 이름과 암호 매개 변수 이름이 없으면 HttpServletRequestWrapper를 사용하여 수정 된 버전의 요청을 Spring Security 로그인 끝점으로 전달하십시오.
이 작업을 수행하려면 web.xml을 수정하여 Spring Security 필터 체인이 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>
출처 : mohchi blog
-
==============================
5.SecurityContextHolder.getContext () 사용 setAuthentication (인증)은 작업을 완료하지만 보안 위험을 초래할 스프링 보안 필터 체인을 우회합니다.
SecurityContextHolder.getContext () 사용 setAuthentication (인증)은 작업을 완료하지만 보안 위험을 초래할 스프링 보안 필터 체인을 우회합니다.
예 : 필자의 경우 사용자가 암호를 재설정 할 때 다시 로그인하지 않고 대시 보드로 가져 오라고 말했습니다. 위의 방법을 사용하면 대시 보드로 이동하지만 동시 로그인을 피하기 위해 필자가 적용한 동시성 필터를 건너 뜁니다. 다음은 작업을 수행하는 코드 조각입니다.
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(empId, password); Authentication auth = authenticationManager.authenticate(authToken); SecurityContextHolder.getContext().setAuthentication(auth);
web.xml의 간단한 변경과 함께 login-processing-url 속성을 사용하십시오.
보안 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"/>
을 포함한다.
<filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/submitLogin</url-pattern> <dispatcher>FORWARD</dispatcher> </filter-mapping>
web.xml에이 코드를 추가하면 실제로 자동 로긴 중에 명시된 순방향 요청을 포워딩하여 스프링 보안 필터 체인에 전달합니다.
희망이 도움이된다.
-
==============================
6.나는 동일한 시나리오를 통합했다. 아래는 코드 스 니펫이다. AuthenticationManager의 인스턴스를 가져 오려면 WebSecurityConfigurerAdapter 클래스의 authenticationManagerBean () 메서드를 재정의해야합니다.
나는 동일한 시나리오를 통합했다. 아래는 코드 스 니펫이다. AuthenticationManager의 인스턴스를 가져 오려면 WebSecurityConfigurerAdapter 클래스의 authenticationManagerBean () 메서드를 재정의해야합니다.
SecurityConfiguration (WebSecurityConfigurerAdapter 확장)
@Bean(name = BeanIds.AUTHENTICATION_MANAGER) @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); }
제어 장치
@Autowired protected AuthenticationManager authenticationManager; @PostMapping("/register") public ModelAndView registerNewUser(@Valid User user,BindingResult bindingResult,HttpServletRequest request,HttpServletResponse response) { ModelAndView modelAndView = new ModelAndView(); User userObj = userService.findUserByEmail(user.getEmail()); if(userObj != null){ bindingResult.rejectValue("email", "error.user", "This email id is already registered."); } if(bindingResult.hasErrors()){ modelAndView.setViewName("register"); return modelAndView; }else{ String unEncodedPwd = user.getPassword(); userService.saveUser(user); modelAndView.setViewName("view_name"); authWithAuthManager(request,user.getEmail(),unEncodedPwd); } return modelAndView; } public void authWithAuthManager(HttpServletRequest request, String email, String password) { UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(email, password); authToken.setDetails(new WebAuthenticationDetails(request)); Authentication authentication = authenticationManager.authenticate(authToken); SecurityContextHolder.getContext().setAuthentication(authentication); }
-
==============================
7.봄 원숭이의 대답은 훌륭하게 작동하지만, 구현할 때 까다로운 문제가 발생했습니다.
봄 원숭이의 대답은 훌륭하게 작동하지만, 구현할 때 까다로운 문제가 발생했습니다.
내 문제는 등록 페이지가 "보안이 없음"으로 설정 되었기 때문입니다. 예 :
<http pattern="/register/**" security="none"/>
나는 이것이 어떤 SecurityContext도 초기화되지 않았으며, 따라서 사용자 등록 후에는 서버 내 인증을 저장할 수 없다고 생각한다.
나는 그것을 IS_AUTHENTICATED_ANONYMOUSLY로 설정함으로써 레지스터 페이지 바이 패스를 변경해야했다.
<http authentication-manager-ref="authMgr"> <intercept-url pattern="/register/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/> ... </http>
-
==============================
8.위 질문에 대한 답변입니다. 컨트롤러에서 :
위 질문에 대한 답변입니다. 컨트롤러에서 :
@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에 넣으려고하지 않았으므로 코드가 실행될 때 논리가 작동하지 않는 이유를 알지 못합니다. 콘솔에 오류나 예외도 없습니다. 그래서 만약 당신이 그것을 잡으려고 시도 못해 나쁜 자격 증명의 예외를 얻을.
-
==============================
9.이것은 Servlet 3 + 통합에 대한 대안입니다. 스프링 시큐리티의 폼 로그인을 사용하고 있다면 로그인 페이지에 위임 할 수 있습니다. 예 :
이것은 Servlet 3 + 통합에 대한 대안입니다. 스프링 시큐리티의 폼 로그인을 사용하고 있다면 로그인 페이지에 위임 할 수 있습니다. 예 :
@PostMapping("/signup") public String signUp(User user) { // encode the password and save the user return "forward:/login"; }
폼에 사용자 이름과 패스워드 필드가 있다고 가정하면 '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(); }
-
==============================
10.당신이 이것을 요구하고 있는지 확신 할 수 없지만 Spring Security 구성에서 "remember-me"태그를 추가 할 수 있습니다. 이렇게하면 클라이언트의 쿠키가 관리되므로 다음에 쿠키가 만료되지 않은 경우 자동으로 로그인됩니다.
당신이 이것을 요구하고 있는지 확신 할 수 없지만 Spring Security 구성에서 "remember-me"태그를 추가 할 수 있습니다. 이렇게하면 클라이언트의 쿠키가 관리되므로 다음에 쿠키가 만료되지 않은 경우 자동으로 로그인됩니다.
<http> ... <remember-me /> </http>
from https://stackoverflow.com/questions/3813028/auto-login-after-successful-registration by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring - 현재 스레드에 대해 실제 트랜잭션을 사용할 수있는 EntityManager가 없음 - 'persist'호출을 안정적으로 처리 할 수 없음 (0) | 2019.01.08 |
---|---|
[SPRING] 스프링에 중복 된 양식 제출 [마감] (0) | 2019.01.08 |
[SPRING] 스프링 보안으로 사용자 업데이트시 권한을 다시로드하는 방법 (0) | 2019.01.08 |
[SPRING] XML 구성없이 @Configuration을 사용하여 데이터베이스 초기화 (0) | 2019.01.08 |
[SPRING] 스프링에 의해 시작된 임베디드 H2 데이터베이스의 내용보기 (0) | 2019.01.08 |