Authentication
使用者身份驗證
登入後的資訊配置
登入後會進行授權 Authorization 詳細資訊可以見下面文章
1. 表單登入
最常見的方式帳號 / 密碼
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | @Configuration@EnableWebSecurity
 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
 @Autowired
 private UserDetailsService userDetailsService;
 
 @Override
 protected void configure(HttpSecurity http) throws Exception {
 http
 .authorizeRequests()
 .anyRequest().authenticated()
 .and()
 .formLogin()
 .loginPage("/login")
 .permitAll();
 }
 
 @Autowired
 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
 auth.userDetailsService(userDetailsService);
 }
 }
 
 
 | 
2. base on memory
基於記憶體的身份驗證適合於簡單應用或開發階段,可以快速設定使用者名和密碼。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | @Autowiredpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
 auth
 .inMemoryAuthentication()
 .withUser("user").password(passwordEncoder().encode("password")).roles("USER")
 .and()
 .withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN");
 }
 
 @Bean
 public PasswordEncoder passwordEncoder() {
 return new BCryptPasswordEncoder();
 }
 
 
 | 
3. JWT 登入
pom 依賴
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | <dependency><groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-security</artifactId>
 </dependency>
 <dependency>
 <groupId>io.jsonwebtoken</groupId>
 <artifactId>jjwt</artifactId>
 <version>0.9.1</version>
 </dependency>
 
 | 
spring config
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | @EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
 @Override
 protected void configure(HttpSecurity http) throws Exception {
 http
 .csrf().disable()
 .authorizeRequests()
 .antMatchers("/login").permitAll()
 .anyRequest().authenticated()
 .and()
 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
 
 http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
 }
 
 @Autowired
 private JwtRequestFilter jwtRequestFilter;
 }
 
 
 | 
JWT util
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | @Componentpublic class JwtUtil {
 private String secret = "yourSecretKey";
 
 public String generateToken(UserDetails userDetails) {
 Map<String, Object> claims = new HashMap<>();
 return Jwts.builder().setClaims(claims).setSubject(userDetails.getUsername())
 .setIssuedAt(new Date(System.currentTimeMillis()))
 .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
 .signWith(SignatureAlgorithm.HS256, secret).compact();
 }
 
 public Boolean validateToken(String token, UserDetails userDetails) {
 final String username = getUsernameFromToken(token);
 return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
 }
 
 private Boolean isTokenExpired(String token) {
 final Date expiration = getExpirationDateFromToken(token);
 return expiration.before(new Date());
 }
 
 private Date getExpirationDateFromToken(String token) {
 return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getExpiration();
 }
 
 private String getUsernameFromToken(String token) {
 return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
 }
 }
 
 
 | 
JWT filter
在每次request 時自動檢查token
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 
 | @Componentpublic class JwtRequestFilter extends OncePerRequestFilter {
 
 @Autowired
 private MyUserDetailsService userDetailsService;
 
 @Autowired
 private JwtUtil jwtUtil;
 
 @Override
 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
 throws ServletException, IOException {
 final String authorizationHeader = request.getHeader("Authorization");
 
 String username = null;
 String jwt = null;
 
 if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
 jwt = authorizationHeader.substring(7);
 username = jwtUtil.getUsernameFromToken(jwt);
 }
 
 if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
 UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
 
 if (jwtUtil.validateToken(jwt, userDetails)) {
 UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
 userDetails, null, userDetails.getAuthorities());
 usernamePasswordAuthenticationToken
 .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
 SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
 }
 }
 chain.doFilter(request, response);
 }
 }
 
 
 | 
密碼加密
加密待補