Автоматический вход после успешной регистрации - PullRequest
29 голосов
/ 28 сентября 2010

привет всем я хочу сделать авто логин после успешной регистрации весной имея в виду: у меня есть защищенная страница, которая требует входа для доступа к ним и я хочу после регистрации пропустить страницу входа и сделать автоматический вход в систему, чтобы пользователь мог видеть эту защищенную страницу. Я использую Spring 3.0, Spring Security 3.0.2 как это сделать?

Ответы [ 10 ]

40 голосов
/ 28 сентября 2010

Это можно сделать с пружинной защитой следующим образом (полупсевдокод):

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);
    }
}

Обновление: содержать только как создать сеанс после регистрации

12 голосов
/ 12 июля 2015

В Servlet 3+ вы можете просто набрать request.login("username","password") и, в случае успеха, перенаправить на любую страницу, которую хотите. Вы можете сделать то же самое для автоматического выхода из системы.

Вот ссылка на раздел документации, в котором говорится об этом: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#servletapi-3

8 голосов
/ 14 июля 2011

Просто комментарий к первому ответу о том, как автоматически подключать аутентификациюManager.

Вам необходимо установить псевдоним, когда вы объявляете менеджер аутентификации в вашем файле applicationantion-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>

Также, когда вы аутентифицируетесь, он может выдать AuthenticationException, поэтому вам нужно его перехватить:

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";
2 голосов
/ 01 августа 2014
  1. Сконфигурируйте web.xml, чтобы Spring Security мог обрабатывать пересылки для URL обработки входа в систему.
  2. Обработка запроса на регистрацию, например создать пользователя, обновить ACL и т. д.
  3. Переслать его с именем пользователя и паролем в адрес для обработки входа для аутентификации.
  4. Получите преимущества всей цепочки фильтров Spring Security, например, защита от фиксации сеанса.

Поскольку пересылки являются внутренними, пользователю будет казаться, что они зарегистрированы и вошли в систему во время одного и того же запроса.

Если ваша форма регистрации не содержит правильных имен параметров имени пользователя и пароля, перешлите измененную версию запроса (используя 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

1 голос
/ 03 августа 2018

Я включил тот же сценарий, ниже приведен фрагмент кода. Чтобы получить экземпляр AuthenticationManager, вам потребуется переопределить метод authenticManagerBean () класса WebSecurityConfigurerAdapter

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);
    }
1 голос
/ 30 июля 2017

Использование SecurityContextHolder.getContext (). SetAuthentication (Authentication) выполняет свою работу, но обходит цепочку фильтров безопасности Spring, что открывает угрозу безопасности.

Например, скажем, в моем случае, когда пользователь сбросил пароль, я хотел, чтобы он снова перешел на панель управления без входа в систему. Когда я использовал вышеупомянутый подход, я перешел на панель мониторинга, но обошел мой фильтр параллелизма, который я применил, чтобы избежать одновременного входа в систему. Вот фрагмент кода, который делает эту работу:

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.

Надеюсь, это поможет

0 голосов
/ 08 сентября 2017

Это альтернатива интеграции Servlet 3+. Если вы используете форму входа в Spring Security, вы можете просто делегировать свою страницу входа. Например:

@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();
}
0 голосов
/ 16 марта 2017

Это ответ на вопрос выше В контроллере:

@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, поэтому никто не понимает, почему логика не работает во время выполнения кода ... и в консоли нет ни ошибок, ни исключений. Так что, если вы не включите его, попробуйте поймать, вы не получите исключение плохих учетных данных.

0 голосов
/ 11 марта 2014

Ответ Spring Monkey прекрасно работает , но я столкнулся с сложной проблемой при его реализации.

Моя проблема заключалась в том, что я установил для страницы регистрации «нет безопасности», например:

<http pattern="/register/**" security="none"/>

Я думаю, что это не вызывает инициализации SecurityContext, и, следовательно, после пользовательских регистраций аутентификация на сервере не может быть сохранена.

Мне пришлось изменить обход страницы регистра, установив его в IS_AUTHENTICATED_ANONYMOUSLY

<http authentication-manager-ref="authMgr">
  <intercept-url pattern="/register/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
  ...
</http>
0 голосов
/ 28 сентября 2010

Я не уверен, что вы спрашиваете об этом, но в вашей конфигурации Spring Security вы можете добавить тег "запомнить меня".Это позволит управлять файлом cookie в вашем клиенте, поэтому в следующий раз (если срок действия файла cookie не истек), вы будете автоматически зарегистрированы.

<http>
    ...
    <remember-me />
</http>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...