Filtre de sécurité Spring avec intégration OIDC pour Casdoor
Casdoor est un IDP open-source qui prend en charge OIDC et divers autres protocoles. Dans cet article, nous verrons comment intégrer Casdoor à votre application en utilisant le filtre de sécurité Spring et OIDC.
Étape 1 : Déployez Casdoor
Tout d'abord, vous devez déployer le serveur Casdoor. Reportez-vous à la documentation officielle pour les instructions d'installation du serveur. Après un déploiement réussi, assurez-vous que :
- Le serveur Casdoor fonctionne à http://localhost:8000.
- Vous pouvez voir la page de connexion Casdoor à http://localhost:7001.
- Vous pouvez tester la fonctionnalité de connexion en vous connectant avec les identifiants
admin
et123
.
Après avoir vérifié ces étapes, suivez les étapes ci-dessous pour intégrer Casdoor à votre application.
Étape 2 : Configurez l'application Casdoor
- Créez une nouvelle application Casdoor ou utilisez-en une existante.
- Ajoutez votre URL de redirection. Vous pouvez trouver plus d'informations sur l'obtention de l'URL de redirection dans la section suivante.
- Obtenez votre
Certificat
sur la page d'édition du certificat. - Ajoutez le fournisseur et les autres paramètres selon les besoins.
Vous pouvez obtenir les valeurs pour Nom de l'application
, Nom de l'organisation
, URL de redirection
, ID client
, Secret client
, et Certificat
sur la page des paramètres de l'application. Nous les utiliserons à l'étape suivante.
Étape 3 : Configurez Spring Security
Vous pouvez personnaliser les paramètres des filtres Spring Security pour traiter les tokens :
Assurez-vous de remplacer les valeurs de configuration par celles de votre propre instance Casdoor, en particulier <Client ID>
et les autres.
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
Pour les applications frontend, la valeur par défaut de <FRONTEND_HOSTNAME>
est localhost:3000
. Dans cette démo, l'URL de redirection est http://localhost:3000/callback
. Assurez-vous de configurer cela dans votre application casdoor
.
Étape 4 : Configurez le Frontend
Vous devez installer casdoor-js-sdk
et configurer le SDK comme suit :
Installez
casdoor-js-sdk
.npm i casdoor-js-sdk
# or
yarn add casdoor-js-sdkConfigurez
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);
Étape 5 : Mettez en place une démo
Créez une application Spring Boot.
Ajoutez quelques configurations pour gérer 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();
}
// ...
}
```
Ajoutez un simple filtre JWT pour intercepter les requêtes qui nécessitent une vérification de token.
@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);
}
}Lorsque l'utilisateur accède à l'interface nécessitant une authentification,
JwtTokenFilter
obtiendra le token de l'en-tête de la requêteAuthorization
et le vérifiera.Définissez un
Controller
pour gérer lorsque l'utilisateur se connecte à Casdoor. Après la connexion de l'utilisateur, il sera redirigé vers le serveur et portera lecode
et lestate
. Le serveur doit alors vérifier l'identité de l'utilisateur auprès de Casdoor et obtenir letoken
à travers ces deux paramètres.@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());
}
}
// ...
}
```
Étape 6 : Essayez la démo
Vous pouvez accéder à l'application frontend via votre navigateur. Si vous n'êtes pas connecté, vous verrez un bouton de connexion. Cliquez dessus, et vous serez redirigé vers la page de connexion Casdoor.
Si vous visitez votre page racine,
Cliquez sur le bouton Connexion Casdoor
, et la page vous redirigera vers la page de connexion de Casdoor.
Après vous être connecté, vous serez redirigé vers /
.