Filtro de Seguridad Spring con integración OIDC para Casdoor
Casdoor es un IDP de código abierto que soporta OIDC y varios otros protocolos. En este artículo, veremos cómo integrar Casdoor con tu aplicación usando el Filtro de Seguridad Spring y OIDC.
Paso 1: Desplegar Casdoor
Primero, necesitas desplegar el servidor Casdoor. Consulta la documentación oficial para instrucciones de instalación del servidor. Después del despliegue exitoso, asegúrate de que:
- El servidor Casdoor está funcionando en http://localhost:8000.
- Puedes ver la página de inicio de sesión de Casdoor en http://localhost:7001.
- Puedes probar la funcionalidad de inicio de sesión iniciando sesión con las credenciales
adminy123.
Después de verificar estos pasos, sigue los pasos a continuación para integrar Casdoor con tu aplicación.
Paso 2: Configurar la Aplicación Casdoor
- Crea una nueva aplicación Casdoor o usa una existente.
- Agrega tu URL de redirección. Puedes encontrar más información sobre cómo obtener la URL de redirección en la siguiente sección.

- Obtén tu
Certificadoen la página de edición de certificados.
- Agrega el proveedor y otros ajustes según sea necesario.
Puedes obtener los valores para Nombre de la Aplicación, Nombre de la Organización, URL de Redirección, ID del Cliente, Secreto del Cliente y Certificado en la página de configuración de la aplicación. Los usaremos en el siguiente paso.
Paso 3: Configurar Spring Security
Puedes personalizar la configuración de los filtros de Spring Security para procesar tokens:
Asegúrate de reemplazar los valores de configuración con los de tu propia instancia de Casdoor, especialmente <Client ID> y los demás.
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
Para aplicaciones frontend, el valor predeterminado de <FRONTEND_HOSTNAME> es localhost:3000. En esta demostración, la URL de redirección es http://localhost:3000/callback. Asegúrate de configurar esto en tu aplicación casdoor.
Paso 4: Configurar Frontend
Necesitas instalar casdoor-js-sdk y configurar el SDK de la siguiente manera:
Instalar
casdoor-js-sdk.npm i casdoor-js-sdk
# or
yarn add casdoor-js-sdkConfigurar
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);
Paso 5: Configurar una Demostración
Crea una aplicación Spring Boot.
Agrega algunas configuraciones para manejar 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();
}
// ...
}
```
Agrega un filtro JWT simple para interceptar solicitudes que requieren verificación 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);
}
}Cuando el usuario accede a la interfaz que requiere autenticación,
JwtTokenFilterobtendrá el token del encabezado de la solicitudAuthorizationy lo verificará.Define un
Controllerpara manejar cuando el usuario inicia sesión en Casdoor. Después de que el usuario inicie sesión, será redirigido al servidor y llevará elcodey elstate. El servidor entonces necesita verificar la identidad del usuario desde Casdoor y obtener eltokena través de estos dos parámetros.@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());
}
}
// ...
}
```
Paso 6: Probar la Demostración
Puedes acceder a la aplicación frontend a través de tu navegador. Si no has iniciado sesión, verás un botón de inicio de sesión. Haz clic en él, y serás redirigido a la página de inicio de sesión de Casdoor.
Si visitas tu página raíz,
Haz clic en el botón Iniciar Sesión Casdoor, y la página te redirigirá a la página de inicio de sesión de Casdoor. 
Después de iniciar sesión, serás redirigido a /. 