我是 Spring Security 的新手,我正在開發一個使用基本身份驗證以保護某些 API 的 Spring Boot 專案。我從現有的教程代碼(Udemy 課程)開始,試圖將其適應我自己的用例。
在這個專案中,我使用這個SecurityConfiguration來配置基本身份驗證。
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
private static String REALM = "REAME";
private static final String[] USER_MATCHER = { "/api/utenti/cerca/**"};
private static final String[] ADMIN_MATCHER = { "/api/utenti/inserisci/**", "/api/utenti/elimina/**" };
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.csrf().disable()
.authorizeRequests()
.antMatchers(USER_MATCHER).hasAnyRole("USER")
.antMatchers(ADMIN_MATCHER).hasAnyRole("ADMIN")
.anyRequest().authenticated()
.and()
.httpBasic().realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint()).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public AuthEntryPoint getBasicAuthEntryPoint()
{
return new AuthEntryPoint();
}
/* To allow Pre-flight [OPTIONS] request from browser */
@Override
public void configure(WebSecurity web)
{
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
@Bean
public BCryptPasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
};
@Bean
@Override
public UserDetailsService userDetailsService()
{
UserBuilder users = User.builder();
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(users
.username("ReadUser")
.password(new BCryptPasswordEncoder().encode("BimBumBam_2018"))
.roles("USER").build());
manager.createUser(users
.username("Admin")
.password(new BCryptPasswordEncoder().encode("MagicaBula_2018"))
.roles("USER", "ADMIN").build());
return manager;
}
}
所以據我了解:
這里id定義了普通用戶可以訪問的API串列和admin用戶可以訪問的API串列:
private static final String[] USER_MATCHER = { "/api/utenti/cerca/**"};
private static final String[] ADMIN_MATCHER = { "/api/utenti/inserisci/**", "/api/utenti/elimina/**" };
在前面的configure()方法中,基本上是說明與USER_MATCHER匹配的 API URL可由具有角色USER的登錄用戶訪問,而具有 URL 匹配ADMIN_MATCHER 的API可由具有角色ADMIN 的登錄用戶訪問。這個解釋正確嗎?
最后,UserDetailsS??ervice bean 簡單地定義了兩個用戶:一個屬于USER “組”,另一個屬于USER和ADMIN “組”。
因此,如果我很好理解,第一個將只能訪問具有端點 URL /api/utenti/cerca/ **的 API,而第二個也將能夠訪問具有端點 URL /api/ 的 API utenti/inserisci/ ** 和/api /utenti/elimina / **
我的推理正確嗎?
現在我懷疑:在這個專案的控制器類中我定義了這個方法:
@RestController
@RequestMapping("api/users")
@Log
public class UserController {
@Autowired
UserService userService;
//@Autowired
//private BCryptPasswordEncoder passwordEncoder;
//@Autowired
//private ResourceBundleMessageSource errMessage;
@GetMapping(value = "/test", produces = "application/json")
public ResponseEntity<String> getTest() throws NotFoundException {
log.info(String.format("****** getTest() START *******"));
return new ResponseEntity<String>("TEST", HttpStatus.OK);
}
..............................................................................................................
..............................................................................................................
..............................................................................................................
}
如您所見,此方法處理對localhost:8019/api/users/test端點的GET請求。
This endpoint URL is not in any of the previous two list related the protected endpoint (it is not into the USER_MATCHER list neither into the ADMIN_MATCHER list. So I expected that simply this endpoint was not protected and accessible to everyone. But performing the previous request using PostMan, I obtain this error message:
HTTP Status 401 : Full authentication is required to access this resource
So basically it seems to me that also if this endpoint not belong to any protected endpoint list it is in some way protected anyway (it seems to me that at least the user must be authenticated (infact trying both the previous user I can obtain the expected output, so it should mean that the endpoint is not protected by the user rule but it is protected againts not authenticated access).
Why? Maybe it depende by the previous configure() method settings, in particular this line?
.anyRequest().authenticated()
In case is it possible to disable in some way to implement something like this:
If a called endpoint belong to one of the previous two lists (USER_MATCHER and ADMIN_MATCHER) --> the user must be authenticated and need to have the correct role.
If a called endpoint not belong to one of the previous lists --> everybody can access, also not authenticated user.
This approach make sense or am I loosing something?
I take this occasion to ask you also another information: do you think that it is possible to configure Spring security of this specific project in order to protect some specific endpoints using the basic authentication and some other specific endpoints using the JWT authentication.
Sone further notes to explain why this last question. This project is a microservice that at the moment is used by another microservice (used to generate JWT token) in order to obtain user information. (the other microservice call an API of this project in order to receive user information so it can generate a JWT token that will be used in my application. The comunication between these 2 microservice must use basic authentication).
Since this project contains all the entity classes used to map the tables related to the users on my DB, my idea was to use this project also for generic user management, so it could include functionality like: add a brand new user, changes information of an existing user, obtain the list of all the users, search a specific user, and so on.
These new APIs will be protected by JWT token because each API can be called from a specific user type having different privileges on the system.
So I am asking if in a situation like this I can add without problem 2 different types of authentication (basic authentication for the API that retrieve a user so the other microservice can obtain this info) and JWT authentication for all the other APIs. It make sense or is it better to create a brand new project for a new user management microservice?
uj5u.com熱心網友回復:
因此,如果我很好理解,第一個將只能訪問具有端點 URL /api/utenti/cerca/** 的 API,而第二個也將能夠訪問具有端點 URL /api/ 的 API utenti/inserisci/** 和 /api/utenti/elimina/**
是的。
為什么?也許它取決于之前的 configure() 方法設定,特別是這一行?
是的,使用 時.anyRequest().authenticated(),任何未匹配的請求都必須進行身份驗證。
如果被叫端點不屬于前面的串列之一 --> 每個人都可以訪問,也不是經過身份驗證的用戶。
您可以通過執行anyRequest().permitAll(). 但這并不是那么安全,因為您允許訪問所有其他端點,相反,您應該保留anyRequest().authenticated()并允許手動訪問特定端點,如下所示:
http
.authorizeRequests()
.antMatchers(USER_MATCHER).hasAnyRole("USER")
.antMatchers(ADMIN_MATCHER).hasAnyRole("ADMIN")
.antMatchers("/api/users/test").permitAll()
.anyRequest().authenticated()
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/366401.html
標籤:java spring 弹簧靴 弹簧安全 弹簧安全休息
