Фільтр Spring Security з інтеграцією OIDC для Casdoor
Casdoor - це відкритий IDP, який підтримує OIDC та різні інші протоколи. У цій статті ми побачимо, як інтегрувати Casdoor з вашим додатком за допомогою фільтру Spring Security та OIDC.
Крок 1: Розгортання Casdoor
Спочатку вам потрібно розгорнути сервер Casdoor. Дивіться офіційну документацію для інструкцій з встановлення сервера. Після успішного розгортання переконайтеся, що:
- Сервер Casdoor працює за адресою http://localhost:8000.
- Ви можете побачити сторінку входу Casdoor за адресою http://localhost:7001.
- Ви можете перевірити функціональність входу, увійшовши за допомогою облікових даних
adminта123.
Після перевірки цих кроків, слідуйте наступним крокам для інтеграції Casdoor з вашим додатком.
Крок 2: Налаштування додатку Casdoor
- Створіть новий додаток Casdoor або використовуйте існуючий.
- Додайте вашу URL-адресу перенаправлення. Більше інформації про отримання URL-адреси перенаправлення ви знайдете в наступному розділі.

- Отримайте ваш
Certificateна сторінці редагування сертифікатів.
- Додайте провайдера та інші налаштування за потребою.
Ви можете отримати значення для Application Name, Organization Name, Redirect URL, Client ID, Client Secret та Certificate на сторінці налаштувань додатку. Ми використаємо їх на наступному кроці.
Крок 3: Налаштування Spring Security
Ви можете налаштувати параметри фільтрів Spring Security для обробки токенів:
Переконайтеся, що ви замінили значення конфігурації на власні, особливо <Client ID> та інші.
server:
port: 8080
casdoor:
endpoint: http://CASDOOR_HOSTNAME:8000
client-id: <Client ID>
client-secret: <Client Secret>
certificate: <Certificate>
organization-name: <Organization Name>
application-name: <Application Name>
redirect-url: http://FRONTEND_HOSTNAME/callback
Для фронтенд-додатків значення за замовчуванням <FRONTEND_HOSTNAME> є localhost:3000. У цьому демо URL-адреса перенаправлення є http://localhost:3000/callback. Переконайтеся, що ви налаштували це у вашому додатку casdoor.
Крок 4: Налаштування фронтенду
Вам потрібно встановити casdoor-js-sdk та налаштувати SDK наступним чином:
Встановіть
casdoor-js-sdk.npm i casdoor-js-sdk
# or
yarn add casdoor-js-sdkНалаштуйте
SDK.import Sdk from "casdoor-js-sdk";
// Serverurl is the URL where spring security is deployed
export const ServerUrl = "http://BACKEND_HOSTNAME:8080";
const sdkConfig = {
serverUrl: "http://CASDOOR_HOSTNAME:8000",
clientId: "<your client id>",
appName: "<your application name>",
organizationName: "<your organization name>",
redirectPath: "/callback",
};
export const CasdoorSDK = new Sdk(sdkConfig);
Крок 5: Налаштування демонстрації
Створіть додаток Spring Boot.
Додайте деякі конфігурації для обробки JWT.
@EnableWebSecurity
public class SecurityConfig {
private final JwtTokenFilter jwtTokenFilter;
public SecurityConfig(JwtTokenFilter jwtTokenFilter) {
this.jwtTokenFilter = jwtTokenFilter;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// enable CORS and disable CSRF
http = http.cors(corsConfig -> corsConfig
.configurationSource(configurationSource())
).csrf().disable();
// set session management to stateless
http = http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and();
// set permissions on endpoints
http.authorizeHttpRequests(authorize -> authorize
.mvcMatchers("/api/redirect-url", "/api/signin").permitAll()
.mvcMatchers("/api/**").authenticated()
);
// set unauthorized requests exception handler
http = http
.exceptionHandling()
.authenticationEntryPoint(
(request, response, ex) -> ResponseUtils.fail(response, "unauthorized")
)
.and();
// add JWT token filter
http.addFilterBefore(
jwtTokenFilter,
UsernamePasswordAuthenticationFilter.class
);
return http.build();
}
// ...
}
```
Додайте простий JWT фільтр для перехоплення запитів, які вимагають перевірки токена.
@Component
public class JwtTokenFilter extends OncePerRequestFilter {
private final CasdoorAuthService casdoorAuthService;
public JwtTokenFilter(CasdoorAuthService casdoorAuthService) {
this.casdoorAuthService = casdoorAuthService;
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain)
throws ServletException, IOException {
// get authorization header and validate
final String header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (!StringUtils.hasText(header) || !header.startsWith("Bearer ")) {
chain.doFilter(request, response);
return;
}
// get jwt token and validate
final String token = header.split(" ")[1].trim();
// get user identity and set it on the spring security context
UserDetails userDetails = null;
try {
CasdoorUser casdoorUser = casdoorAuthService.parseJwtToken(token);
userDetails = new CustomUserDetails(casdoorUser);
} catch (CasdoorAuthException exception) {
logger.error("casdoor auth exception", exception);
chain.doFilter(request, response);
return;
}
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails,
null,
AuthorityUtils.createAuthorityList("ROLE_casdoor")
);
authentication.setDetails(
new WebAuthenticationDetailsSource().buildDetails(request)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}
}Коли користувач звертається до інтерфейсу, що вимагає аутентифікації,
JwtTokenFilterотримує токен з заголовка запитуAuthorizationта перевіряє його.Визначте
Controller, щоб обробити, коли користувач входить до Casdoor. Після входу користувача він буде перенаправлений на сервер і нестимеcodeтаstate. Сервер тоді повинен перевірити особу користувача з Casdoor та отриматиtokenчерез ці два параметри.@RestController
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
private final CasdoorAuthService casdoorAuthService;
// ...
@PostMapping("/api/signin")
public Result signin(@RequestParam("code") String code, @RequestParam("state") String state) {
try {
String token = casdoorAuthService.getOAuthToken(code, state);
return Result.success(token);
} catch (CasdoorAuthException exception) {
logger.error("casdoor auth exception", exception);
return Result.failure(exception.getMessage());
}
}
// ...
}
```
Крок 6: Спробуйте демонстрацію
Ви можете отримати доступ до фронтенд-додатку через ваш браузер. Якщо ви не увійшли, ви побачите кнопку входу. Натисніть на неї, і ви будете перенаправлені на сторінку входу Casdoor.
Якщо ви відвідуєте вашу кореневу сторінку,
Натисніть кнопку Casdoor Login, і сторінка перенаправить вас на сторінку входу Casdoor. 
Після входу ви будете перенаправлені на /. 