Java Reference
In-Depth Information
After the user is authenticated, the
filter()
method creates a custom
SecurityContext
implementation within an inner anonymous class. It then overrides the existing
Secur-
ityContext
by calling
ContainerRequestContext.setSecurityContext()
. The
Secur-
ityContext.getUserPrincipal()
is implemented to return a
Principal
initialized with
the username sent in the
Authorization
header. Other JAX-RS code can now inject this
custom
SecurityContext
to find out who the user principal is.
The algorithm for generating a one-time password is pretty simple. Let's take a look:
src/main/java/com/restfully/shop/features/OTP.java
public
public class
class
OTP
OTP
{
public
public static
static
String
generateToken
(
String secret
)
{
long
long
minutes
=
System
.
currentTimeMillis
() /
1000
/
60
;
String concat
=
secret
+
minutes
;
MessageDigest digest
=
null
null
;
try
try
{
digest
=
MessageDigest
.
getInstance
(
"MD5"
);
}
catch
catch
(
NoSuchAlgorithmException e
)
{
throw
throw new
new
IllegalArgumentException
(
e
);
}
byte
byte
[]
hash
=
digest
.
digest
(
concat
.
getBytes
(
Charset
.
forName
(
"UTF-8"
)));
return
return
Base64
.
encodeBytes
(
hash
);
}
}
OTP
is a simple class. It takes any arbitrary password and combines it with the current time in
minutes to generate a new
String
object. An MD5 hash is done on this
String
object. The
hash bytes are then Base 64-encoded using a RESTEasy-specific library and returned as a
String
.
The
@OTPAuthenticated
annotation is then applied to two methods in the
CustomerRe-
source
class to secure access to them:
src/main/java/com/restfully/shop/services/CustomerResource.java
@GET
@Path
(
"{id}"
)
@Produces
(
"application/xml"
)
@OTPAuthenticated