Как использовать аутентификацию Spring Boot с сеансом Redis - PullRequest
0 голосов
/ 03 июня 2018

Я пытаюсь изучить Spring Boot, написав простое приложение REST, которое будет регистрировать пользователей (POST /login) и отображать информацию о текущем пользователе (GET /).Я использую Redis для сессий.

POST /login работает должным образом: он возвращает субъект и устанавливает cookie-файл сеанса как в браузере, так и в Redis.

Последующие GET / запросы, однако, возвращают anonymousUser.Чего мне не хватает?

pom.xml:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

application.properties:

spring.session.store-type=redis

server.servlet.session.timeout=3600s
spring.session.redis.flush-mode=on-save
spring.session.redis.namespace=spring:session

spring.redis.host=localhost
spring.redis.port=6379

IndexController.java:

@Controller
public class IndexController {

    private AuthenticationManager authenticationManager;

    IndexController(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @GetMapping
    ResponseEntity index(HttpServletRequest request, HttpSession session) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return new ResponseEntity<>(authentication.getPrincipal(), HttpStatus.OK);
    }

    @PostMapping("/login")
    ResponseEntity login(@RequestBody LoginRequest loginRequest) {
        String username = loginRequest.getUsername();
        String password = loginRequest.getPassword();
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
        Authentication authentication = this.authenticationManager.authenticate(token);
        return new ResponseEntity<>(authentication.getPrincipal(), HttpStatus.OK);
    }
}

Config.java:

@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@EnableRedisHttpSession
@Configuration
public class Config extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
            .and()
            .csrf()
            .disable()
            .authorizeRequests()
            .anyRequest()
            .permitAll();
    }
}

1 Ответ

0 голосов
/ 11 июня 2018

Оказывается, я забыл установить authentication в методе login.Это правильный код.

@PostMapping("/login")
ResponseEntity login(@RequestBody LoginRequest loginRequest) {
    String username = loginRequest.getUsername();
    String password = loginRequest.getPassword();
    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
    Authentication authentication = this.authenticationManager.authenticate(token);
    // vvv THIS vvv
    SecurityContextHolder
        .getContext()
        .setAuthentication(authentication);
    return new ResponseEntity<>(authentication.getPrincipal(), HttpStatus.OK);
}

См. https://docs.spring.io/spring-security/site/docs/5.0.5.RELEASE/reference/htmlsingle/#what-is-authentication-in-spring-security

...