iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
Software Development

Spring boot 從零到寫出ChatGPT系列 第 26

Spring boot 從零開始 (26) - Spring security 帳號密碼身分驗證

  • 分享至 

  • xImage
  •  

這兩天分享了Spring Security建立方式,UserService以及Spring Security升版之後的用法。
今天廢話不多說,我們就直接切入正題吧 !!!

使用 InMemoryUserDetailsManager

我們在ApSecurityConfig中,透過InMemoryUserDetailsManager來實作UserService,建立帳號與密碼並儲存於記憶體中,範例如下,我們建立了兩組帳號與密碼,並且分別給他們對應的角色權限

@Configuration
@EnableWebSecurity
public class ApSecurityConfig {

    @Bean
    public UserDetailsService userDetailsService() throws Exception {
        User.UserBuilder users = User.withDefaultPasswordEncoder();
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(users.username("user").password("user").roles(String.valueOf(UserRole.USER)).build());
        manager.createUser(users.username("admin").password("admin").roles(String.valueOf(UserRole.USER), String.valueOf(UserRole.ADMIN)).build());
        return manager;
    }
}    

接著我們就可以啟動應用程式,並使用以下網址「http://localhost:8080/login」
使用我們剛剛在上面建立的帳密登入看看,這個時候我們會看到成功登入了,但會出現Whitelabel Error Page,這個時候就是在跟我們說要建立下一步驟了。

針對API透過Role的方式來控管

我們接續著上面建立的ApSecurityConfig,我們繼續建立filterChain來管理API

  • permitAll() : 這邊是指不用任何的驗證授權就可以訪問,所以依照我們底下的設定,代表pulic/...都可以直接訪問
    @Bean
    public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(
                        requests -> requests
                                .requestMatchers("/public/**").permitAll()
                                .requestMatchers("/admin/**").hasRole("ADMIN")
                                .anyRequest()
                                .authenticated()
                )
                .formLogin(withDefaults())
                .logout(withDefaults());
        return http.build();
    }

所以我們來建立對應的controller來等等測試看看

@RestController
@Slf4j
@RequestMapping(name = "/public", consumes = MediaType.APPLICATION_JSON_VALUE,
        produces = MediaType.APPLICATION_JSON_VALUE)
public class PublicController {
    @Autowired
    private BookRepo bookRepo;
    @GetMapping("books")
    public ResponseEntity<List<Book>> getUserName() {
        return ResponseEntity.ok(bookRepo.findAll());
    }
}

接著我們就可以啟動應用程式,並使用以下網址「http://localhost:8080/login」,我們等等用兩個帳號登入測試看看是否可以都正常訪問到API

  1. 我們先用帳號:user進行登入
    https://ithelp.ithome.com.tw/upload/images/20241010/20112118rJg7GWMroG.png
  2. 接著我們就來訪問看看 「http://localhost:8080/public/books」,我們可以得到以下結果
    https://ithelp.ithome.com.tw/upload/images/20241010/20112118H69NdNWK8k.png
  • hasRole : 這樣就需要有指定的角色權限才可以訪問API,在我們上面的範例,登入的帳號需要是ADMIN角色才可以使用,那我們就用以下API進行測試
    @GetMapping("admin/book/{bookId}")
    @Operation(summary = "Gets book by ID", description= "Book must exist")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "Success to find book"),
            @ApiResponse(responseCode = "404", description = "Book not found")})
    public ResponseEntity<Book> getUserName(@PathVariable("bookId") int bookId) throws NotBoundException, BadRequestException {
        Book response = ironService.findBookById(bookId);
        if(Objects.isNull(response)) {
            return ResponseEntity.notFound().build();
        } else {
            return ResponseEntity.ok(ironService.findBookById(bookId));
        }
    }

1.我們先用帳號:user進行登入
2.接著我們就來訪問看看 「http://localhost:8080/admin/book/1」,我們可以得到以下結果,我們發現沒有權限訪問,所以就直接變成Whitelabel Error Page
https://ithelp.ithome.com.tw/upload/images/20241010/20112118OePlzXiPPh.png
3.那我們就用帳號:admin進行登入
4.接著我們就來訪問看看 「http://localhost:8080/admin/book/1」,我們可以得到以下結果,我們有可以順利訪問API
https://ithelp.ithome.com.tw/upload/images/20241010/20112118ZolzbEU84o.png

統整

我們可以透過Spring Security來進行帳號密碼驗證,如果有興趣的大家也可以再研究看看Basic Auth跟JWT的驗證方式,另外我們也可以自訂filterChain來針對介面設定是否需要授權、驗證,讓我們的Application安全性更加升級。

參考來源


上一篇
Spring boot 從零開始 (25) - Spring security 5.7 升級到6.x之間的改動
下一篇
Spring boot 從零開始 (27) - 甚麼是OpenAI API & 帳號申請
系列文
Spring boot 從零到寫出ChatGPT30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言