前一篇 (
Spring Security: 資料庫認證、授權) 說明了怎麼使用資料庫認證,但是,看完可能會有點混淆,似乎 Spring Security 的認證、授權,就一定要使用到 WebSecurityConfigurerAdapter,Spring Security 一定要在 Web 中使用? 當然不是! 這裡以官方文件 Spring Security Reference 中的範例來說明。
public class AuthenticationExample {
private static AuthenticationManager am = new SampleAuthenticationManager();
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("Please enter your username:");
String name = in.readLine();
System.out.println("Please enter your password:");
String password = in.readLine();
try {
Authentication request = new UsernamePasswordAuthenticationToken(name, password);
Authentication result = am.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
break;
} catch(AuthenticationException e) {
System.out.println("Authentication failed: " + e.getMessage());
}
}
System.out.println("Successfully authenticated. Security context contains: " +
SecurityContextHolder.getContext().getAuthentication());
}
}
- SampleAuthenticationManager
public class SampleAuthenticationManager implements AuthenticationManager {
static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();
static {
AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
}
public Authentication authenticate(Authentication auth)
throws AuthenticationException {
if (auth.getName().equals(auth.getCredentials())) {
return new UsernamePasswordAuthenticationToken(
auth.getName(), auth.getCredentials(), AUTHORITIES
);
}
throw new BadCredentialsException("Bad Credentials");
}
}
Please enter your username:
bob
Please enter your password:
password
Authentication failed: Bad Credentials
Please enter your username:
bob
Please enter your password:
bob
Successfully authenticated. Security context contains: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@441d0230: Principal: bob; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
程式簡單的要使用者從命令列輸入帳號、密碼,然後檢查帳密是否合法,這裡把帳密當成同一字串,所以第二次輸入 bob / bob 時,認證才成功,現在來說明一下程式。 SampleAuthenticationManager 這個類別實作 AuthenticationManager 介面,這個介面很簡單,只有一個 method - authenticate(Authentication authentication),只需要傳入一個實作 Authentication 介面的類別物件就行,範例傳入的是 UsernamePasswordAuthenticationToken 類別的物件。 UsernamePasswordAuthenticationToken 這個類別非常簡單的,它實作 Authentication,用來放使用者的帳號、密碼 (如果必要還可以放角色,範例放入了預設的角色 USER。),然後在 authenticate method 裡,就可以看到,我們取出帳號、密碼來比對,相同就回傳 token,失敗拋出 exception。 回到主程式,可以看到取得 authenticate 的回傳值後,範例程式將它放入 SecurityContextHolder 的 context 的 authentication 裡,為什麼?
Authentication result = am.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
這是 spring security 的要求,在認證成功後,要將使用者的 token 放入 SecurityContext 裡,未來 spring security 需要使用者的權限時,會自行取用。
沒有留言:
張貼留言