javax-security-cdi-extension

javax.security CDI Portable Extension

License

License

Categories

Categories

Security
GroupId

GroupId

com.github.exabrial
ArtifactId

ArtifactId

javax-security-cdi-extension
Last Version

Last Version

1.0.0
Release Date

Release Date

Type

Type

jar
Description

Description

javax-security-cdi-extension
javax.security CDI Portable Extension
Project URL

Project URL

https://github.com/exabrial/javax-security-cdi-extension
Source Code Management

Source Code Management

https://github.com/exabrial/javax-security-cdi-extension/tree/master

Download javax-security-cdi-extension

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.exabrial/javax-security-cdi-extension/ -->
<dependency>
    <groupId>com.github.exabrial</groupId>
    <artifactId>javax-security-cdi-extension</artifactId>
    <version>1.0.0</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.exabrial/javax-security-cdi-extension/
implementation 'com.github.exabrial:javax-security-cdi-extension:1.0.0'
// https://jarcasting.com/artifacts/com.github.exabrial/javax-security-cdi-extension/
implementation ("com.github.exabrial:javax-security-cdi-extension:1.0.0")
'com.github.exabrial:javax-security-cdi-extension:jar:1.0.0'
<dependency org="com.github.exabrial" name="javax-security-cdi-extension" rev="1.0.0">
  <artifact name="javax-security-cdi-extension" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.exabrial', module='javax-security-cdi-extension', version='1.0.0')
)
libraryDependencies += "com.github.exabrial" % "javax-security-cdi-extension" % "1.0.0"
[com.github.exabrial/javax-security-cdi-extension "1.0.0"]

Dependencies

compile (2)

Group / Artifact Type Version
org.slf4j : slf4j-api jar 1.7.25
org.apache.deltaspike.core : deltaspike-core-api jar 1.8.2

provided (1)

Group / Artifact Type Version
javax : javaee-api jar 7.0

Project Modules

There are no modules declared in this project.

javax-security-cdi-extension

A CDI Portable Extension for Java EE 7 (and probably Java EE 8) that allows you to use @RolesAllowed({"role-name"}) on CDI Beans and their Methods.

TL;DR

Makes this work:

@ApplicationScoped
@RolesAllowed({"required-role"})
public class MyBusinessLogic {
 public void wahoo() {
  // only invokable by users with required-role
 }
}

If the person doesn't have the the required role, the DefaultJavaXSecurityFailureHandler class throws a new WebApplicationException(Response.Status.UNAUTHORIZED). This behavior is customizable, see below.

Motivation

A common mistake is that someone sees javax.annotation.security and applies it to a CDI bean, thinking since it belongs to a general javax package, and not a EJB package. Well it doesn't sadly, it only works for EJB (Stateless, Stateful, Singleton, and MDB).

License

All files in this project are licensed Apache Source License 2.0. Please consider submitting any changes you make back to this project!

Caveats

You must be in a servlet lifecycle. Said differently: you have to be handling an HTTP Request. If the bean is being called by another initiator like an MDB or Timer, you'll run into some problems (and you probably have a bug in your program too).

Usage

Maven Coordinates:

<dependency>
 <groupId>com.github.exabrial</groupId>
 <artifactId>javax-security-cdi-extension</artifactId>
 <version>1.0.0</version>
 <scope>runtime</scope>
</dependency>

If you are customizing the behavior, your scope will need to be compile.

Setup

You must have authentication setup in your webapp.

Example WEB-INF/web.xml for Basic auth:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
 version="3.1"
 xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
 <login-config>
  <auth-method>BASIC</auth-method>
 </login-config>
</web-app>

Configuration/Customization

Logging

If you have a CDI @Producer for SLF4J loggers, the extension will produce useful warning logs on failures. You probably want to know if a bunch of login failures are happening in your apps, so I suggest doing this.

Example CDI Logger Producer:

 @Produces
 @Dependent
 public Logger createLogger(final InjectionPoint injectionPoint) {
  Class<?> declaringClass = injectionPoint.getMember().getDeclaringClass();
  return LoggerFactory.getLogger(declaringClass);
 }

Disabling

If you want to disable security (maybe for localhost development), you can disable it by creating a Boolean CDI Producer with the qualifer @com.github.exabrial.cdi.javaxsecurity.SkipSecurity:

Example of skipping security:

 @Produces
 @SkipSecurity
 public Boolean skipSecurity() {
  return Boolean.TRUE;
 }

Customizing Authentication/Authorization Failure modes

You can implement the com.github.exabrial.cdi.javaxsecurity.JavaXSecurityFailureHandler interface and create custom behavior when things go wrong. Implement the interface, then mark it as an @Alternative and with @Priority.

Example:

@ApplicationScoped
@Alternative
@Priority
public class MyJavaXSecurityFailureHandler implements JavaXSecurityFailureHandler {
 @Override
 public void authenticationFailure() {
  // ...
 }
 
 @Override
 public void authorizationFailure(Class<? extends Object> targetClass, Method targetMethod, String roleName) {
  // ...
 }
}

Versions

Version
1.0.0