Автоматический вход после успешной регистрации

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

Ответы на вопрос(10)

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

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

Решение Вопроса

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

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

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

 funky-nd03 нояб. 2017 г., 06:13
Пишу с ноября 2017, работает
 Brad Parks22 авг. 2012 г., 13:46
для способа сделать это, не зная пароль пользователя, проверьте здесь:stackoverflow.com/a/12057327/26510
 Mahmoud Saleh13 окт. 2010 г., 13:11
я получил следующее исключение ??? org.springframework.security.authentication.BadCredentialsException: неверные учетные данные
 Shravan Ramamurthy12 дек. 2015 г., 07:54
Я не уверен, как мне получить RequestCache и authenticManager. Когда я попробовал описанное выше решение, Spring Security перенаправляет пользователя на страницу входа.
 korosmatick03 мая 2017 г., 13:49
Если вы используете кодировщик пароля, передайте незашифрованный пароль методу UsernamePasswordAuthenticationToken ()
 Mahmoud Saleh13 окт. 2010 г., 13:54
предыдущее исключение решено, но я получил следующее исключение org.springframework.security.access.AccessDeniedException: доступ запрещен, более подробная информация здесь:stackoverflow.com/questions/3923296/...
 Michael Dausmann27 окт. 2014 г., 10:56
requestCache что-нибудь делает?
 Jeewantha Samaraweera27 авг. 2016 г., 08:17
@ShravanRamamurthy После реализации этого в моем приложении extjs, интегрированном в Spring, у меня возникла та же проблема. Это работает только для меня после замены существующего ключа весеннего контекста безопасности в сеансе на новый аутентифицированный контекст безопасности.request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
 Mahmoud Saleh29 сент. 2010 г., 10:05
не правильно, я уже знаю целевую страницу, но она требует входа в систему, чтобы увидеть ее, и я не хочу идти на страницу входа в систему и хочу сделать внутренний автоматический вход, понял?
 Spring Monkey29 сент. 2010 г., 15:15
Я обновил свой код для автоматического входа в систему после регистрации.
 nyxz22 окт. 2014 г., 11:30
Этот ответ давно. Это правильный способ выполнить автоматический вход при регистрации? Я знаю, что это работает, но есть ли лучший способ сейчас?

Это альтернатива интеграции 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«sdefaultSuccessUrl (пример настройки безопасности ниже). Это также очищает ваш контроллер, не требуяHttpServletRequest параметр.

@Override
public void configure(HttpSecurity http) {
    http.authorizeRequests()
            .antMatchers("/", "/signup").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/home", true)
            .permitAll();
}

Ответ 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>

Просто комментарий к первому ответу о том, как автоматически подключить аутентификацию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";

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

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

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

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

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

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

 LuTHieR25 мая 2016 г., 10:57
Работает отлично, и это намного проще, чем любой другой ответ. Спасибо!
 justderb14 сент. 2015 г., 02:16
Основной метод в основном делаетstackoverflow.com/a/3815189/1178781 под капотом. Так что это отлично сработало для меня!
 Shravan Ramamurthy12 дек. 2015 г., 08:00
Большое спасибо .. это сработало как очарование для меня ..

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

<http>
    ...
    <remember-me />
</http>
 Mahmoud Saleh28 сент. 2010 г., 16:25
это не то, о чем ты спрашиваешь

Я включил тот же сценарий, ниже приведен фрагмент кода. Чтобы получить экземпляр AuthenticationManager, вам необходимо переопределить метод authenticationManagerBean () класса 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);
    }
Сконфигурируйте web.xml, чтобы Spring Security мог обрабатывать пересылки для URL обработки входа в систему.Обработка запроса на регистрацию, например, создать пользователя, обновить ACL и т. д.Перешлите его с именем пользователя и паролем в адрес для обработки входа в систему для аутентификации.Получите преимущества всей цепочки фильтров 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>

Источник: блог Мохчи

Ваш ответ на вопрос