Inscripción
improve this page | report issueVisión general
Este ejemplo muestra un proceso de inscripción personalizado y una autorización de paso ascendente. Durante el proceso de inscripción de una única vez, se le pide al usuario que introduzca su nombre de usuario y contraseña y que defina el código PIN.
Requisitos previos: Asegúrese de leer los tutoriales ExternalizableSecurityCheck y Paso ascendente.
Ir a:
- Flujo de aplicación
- Almacenamiento de datos en atributos persistentes
- Comprobaciones de seguridad
- Aplicaciones de ejemplo
Flujo de aplicación
- Cuando se inicia la aplicación por primera vez (antes de realizar la inscripción), muestra la IU con dos botones: Obtener datos públicos e Inscribirse.
- Cuando el usuario pulsa el botón Inscribirse para iniciar la inscripción, visualiza un formulario de inicio de sesión y se le solicita que establezca un código PIN.
- Cuando el usuario se haya inscrito correctamente, la IU incluirá cuatro botones: Obtener datos públicos, Obtener saldo, Obtener transacciones, y Cerrar sesión. El usuario puede acceder a los cuatro botones sin tener que escribir el código PIN.
- Cuando se inicia la aplicación una segunda vez (después de haber realizado la inscripción), todavía se muestran los cuatro botones en la IU. Sin embargo, cuando el usuario hace clic en el botón Obtener transacciones*, se le solicita que introduzca el código PIN.
Si el usuario comete tres fallos al introducir el código PIN, se le solicita que vuelva a autenticarse con un nombre de usuario y una contraseña y que restablezca el código PIN.
Almacenamiento de datos en atributos persistentes
Puede guardar los datos protegidos en el objeto PersistentAttributes
, que es un contenedor para los atributos personalizados de un cliente registrado. Se puede acceder al objeto desde una clase de comprobación de seguridad o desde una clase de recurso de adaptador.
En la aplicación de ejemplo proporcionada, el objeto PersistentAttributes
se utiliza en la clase de recurso de adaptador para almacenar el código PIN:
-
El recurso setPinCode añade el atributo pinCode y llama el método
AdapterSecurityContext.storeClientRegistrationData()
para que almacene los cambios.@POST @OAuthSecurity(scope = "setPinCode") @Path("/setPinCode/{pinCode}") public Response setPinCode(@PathParam("pinCode") String pinCode){ ClientData clientData = adapterSecurityContext.getClientRegistrationData(); clientData.getProtectedAttributes().put("pinCode", pinCode); adapterSecurityContext.storeClientRegistrationData(clientData); return Response.ok().build(); }
users
tiene una llave denominadaEnrollmentUserLogin
que contiene el objetoAuthenticatedUser
. -
El recurso Cancelar inscripción suprime el atributo pinCode y llama el método
AdapterSecurityContext.storeClientRegistrationData()
para que almacene los cambios.@DELETE @OAuthSecurity(scope = "unenroll") @Path("/unenroll") public Response unenroll(){ ClientData clientData = adapterSecurityContext.getClientRegistrationData(); if (clientData.getProtectedAttributes().get("pinCode") != null){ clientData.getProtectedAttributes().delete("pinCode"); adapterSecurityContext.storeClientRegistrationData(clientData); } return Response.ok().build(); }
Comprobaciones de seguridad
El ejemplo de inscripción contiene tres comprobaciones de seguridad:
EnrollmentUserLogin
La comprobación de seguridad EnrollmentUserLogin
protege el recurso setPinCode para que solo los usuarios autenticados puedan definir un código PIN. Esta verificación de seguridad se ha creado para caducar rápido y para mantenerse solo durante la “primera experiencia”. Es idéntico a la comprobación de seguridad UserLogin
descrita en el tutorial Implementación de UserAuthenticationSecurityCheck excepto por los métodos isLoggedIn
y getRegisteredUser
adicionales.
El método isLoggedIn
devuelve true
si el estado de la verificación de seguridad es igual al valor ÉXITO y false
si es lo contrario.
El método getRegisteredUser
devuelve el usuario autenticado.
public boolean isLoggedIn(){
return getState().equals(STATE_SUCCESS);
}
public AuthenticatedUser getRegisteredUser() {
return registrationContext.getRegisteredUser();
}
EnrollmentPinCode
La comprobación de seguridad EnrollmentPinCode
protege el recurso Obtener transacciones y es similar a la comprobación de seguridad PinCodeAttempts
descrita en el tutorial Implementación de CredentialsValidationSecurityCheck, salvo por algunas modificaciones.
En el ejemplo de este tutorial, EnrollmentPinCode
**depende de ** EnrollmentUserLogin
. Cuando haya iniciado sesión correctamente en EnrollmentUserLogin
, solo se le solicita al usuario que introduzca un código PIN.
@SecurityCheckReference
private transient EnrollmentUserLogin userLogin;
Cuando se inicie la aplicación por primera vez y el usuario se haya inscrito correctamente, deberá poder acceder al recurso Obtener transacciones sin tener que indicar el código PIN que ha establecido. Para este propósito, el método authorize
utiliza el método EnrollmentUserLogin.isLoggedIn
para verificar si el usuario ha iniciado sesión. Esto significa que si siempre y cuando EnrollmentUserLogin
no haya caducado, el usuario puede acceder a Obtener transacciones.
@Override
public void authorize(Set<String> scope, Map<String, Object> credentials, HttpServletRequest request, AuthorizationResponse response) {
if (userLogin.isLoggedIn()){
setState(STATE_SUCCESS);
response.addSuccess(scope, userLogin.getExpiresAt(), getName());
}
}
Si el usuario comete tres fallos al introducir el código PIN, el tutorial está diseñado para que el atributo pinCode se suprima antes de solicitar al usuario que se autentique, utilizando el nombre de usuario y la contraseña y restableciendo el código PIN.
@Override
public void authorize(Set<String> scope, Map<String, Object> credentials, HttpServletRequest request, AuthorizationResponse response) {
PersistentAttributes attributes = registrationContext.getRegisteredProtectedAttributes();
if (userLogin.isLoggedIn()){
setState(STATE_SUCCESS);
response.addSuccess(scope, userLogin.getExpiresAt(), getName());
} else {
super.authorize(scope, credentials, request, response);
if (getState().equals(STATE_BLOCKED)){
attributes.delete("pinCode");
}
}
}
El método validateCredentials
es el mismo que en la comprobación de seguridad PinCodeAttempts
, pero en este caso las credenciales se comparan con el atributo pinCode.
@Override
protected boolean validateCredentials(Map<String, Object> credentials) {
PersistentAttributes attributes = registrationContext.getRegisteredProtectedAttributes();
if(credentials!=null && credentials.containsKey("pin")){
String pinCode = credentials.get("pin").toString();
if(pinCode.equals(attributes.get("pinCode"))){
errorMsg = null;
return true;
}
else {
errorMsg = "The pin code is not valid. Hint: " + attributes.get("pinCode");
}
}
else{
errorMsg = "The pin code was not provided.";
}
//In any other case, credentials are not valid
return false;
}
IsEnrolled
La comprobación de seguridad IsEnrolled
protege:
- El recurso getBalance para que solo los usuarios inscritos puedan utilizar el saldo.
- El recurso transacciones de manera que solo los usuarios inscritos pueden obtener las transacciones.
- El recurso cancelar inscripción por lo que solo es posible suprimir el pinCode si se ha definido antes.
Creación de la comprobación de seguridad
Cree un adaptador Java y añada una clase Java denominada IsEnrolled
que amplíe ExternalizableSecurityCheck
.
public class IsEnrolled extends ExternalizableSecurityCheck{
protected void initStateDurations(Map<String, Integer> durations) {}
public void authorize(Set<String> scope, Map<String, Object> credentials, HttpServletRequest request, AuthorizationResponse response) {}
public void introspect(Set<String> scope, IntrospectionResponse response) {}
}
La clase de configuración IsEnrolledConfig
Cree una clase de configuración IsEnrolledConfig
que amplíe ExternalizableSecurityCheckConfig
:
public class IsEnrolledConfig extends ExternalizableSecurityCheckConfig {
public int successStateExpirationSec;
public IsEnrolledConfig(Properties properties) {
super(properties);
successStateExpirationSec = getIntProperty("expirationInSec", properties, 8000);
}
}
Añada el método createConfiguration
en la clase IsEnrolled
:
public class IsEnrolled extends ExternalizableSecurityCheck{
@Override
public SecurityCheckConfiguration createConfiguration(Properties properties) {
return new IsEnrolledConfig(properties);
}
}
El método initStateDurations
Establezca la duración para el estado ÉXITO en successStateExpirationSec
:
@Override
protected void initStateDurations(Map<String, Integer> durations) {
durations.put (SUCCESS_STATE, ((IsEnrolledConfig) config).successStateExpirationSec);
}
El método authorize
El ejemplo de código verifica si el usuario está inscrito y devuelve un error o un acierto en consecuencia:
public void authorize(Set<String> scope, Map<String, Object> credentials, HttpServletRequest request, AuthorizationResponse response) {
PersistentAttributes attributes = registrationContext.getRegisteredProtectedAttributes();
if (attributes.get("pinCode") != null){
setState(SUCCESS_STATE);
response.addSuccess(scope, getExpiresAt(), this.getName());
} else {
setState(STATE_EXPIRED);
Map <String, Object> failure = new HashMap<String, Object>();
failure.put("failure", "User is not enrolled");
response.addFailure(getName(), failure);
}
}
-
En caso de que exista el atributo
pinCode
: - Establezca el estado en ÉXITO utilizando el método
setState
. -
Añada el valor éxito en el objeto de respuesta utilizando el método
addSuccess
. -
En caso de que el atributo
pinCode
no exista: - Establezca el estado CADUCADO utilizando el método
setState
. - Añada el valor error en el objeto de respuesta utilizando el método
addFailure
.
La comprobación de seguridad IsEnrolled
depende de EnrollmentUserLogin
:
@SecurityCheckReference
private transient EnrollmentUserLogin userLogin;
Establezca el usuario activo añadiendo el código siguiente:
public void authorize(Set<String> scope, Map<String, Object> credentials, HttpServletRequest request, AuthorizationResponse response) {
PersistentAttributes attributes = registrationContext.getRegisteredProtectedAttributes();
if (attributes.get("pinCode") != null){
// Is there a user currently active?
if (!userLogin.isLoggedIn()){
// If not, set one here.
authorizationContext.setActiveUser(userLogin.getRegisteredUser());
}
setState(SUCCESS_STATE);
response.addSuccess(scope, getExpiresAt(), this.getName());
} else {
setState(STATE_EXPIRED);
Map <String, Object> failure = new HashMap<String, Object>();
failure.put("failure", "User is not enrolled");
response.addFailure(getName(), failure);
}
}
A continuación, el recurso transacciones
obtiene el objeto actual AuthenticatedUser
para presentar el nombre de visualización:
@GET
@Produces(MediaType.TEXT_PLAIN)
@OAuthSecurity(scope = "transactions")
@Path("/transactions")
public String getTransactions(){
AuthenticatedUser currentUser = securityContext.getAuthenticatedUser();
return "Transactions for " + currentUser.getDisplayName() + ":\n{'date':'12/01/2016', 'amount':'19938.80'}";
}
Para obtener más información acerca de
securityContext
, consulte la sección API Seguridad en el tutorial de adaptador Java.
Añada el usuario registrado al objeto de respuesta de la forma siguiente:
public void authorize(Set<String> scope, Map<String, Object> credentials, HttpServletRequest request, AuthorizationResponse response) {
PersistentAttributes attributes = registrationContext.getRegisteredProtectedAttributes();
if (attributes.get("pinCode") != null){
// Is there a user currently active?
if (!userLogin.isLoggedIn()){
// If not, set one here.
authorizationContext.setActiveUser(userLogin.getRegisteredUser());
}
setState(SUCCESS_STATE);
response.addSuccess(scope, getExpiresAt(), getName(), "user", userLogin.getRegisteredUser());
} else {
setState(STATE_EXPIRED);
Map <String, Object> failure = new HashMap<String, Object>();
failure.put("failure", "User is not enrolled");
response.addFailure(getName(), failure);
}
}
En el código de ejemplo, el método handleSuccess
del manejador de desafíos IsEnrolled
utiliza el objeto de usuario para presentar el nombre de visualización.
Aplicaciones de ejemplo
Comprobación de seguridad
Las comprobaciones de seguridad EnrollmentUserLogin
, EnrollmentPinCode
, e IsEnrolled
están disponibles en el proyecto SecurityChecks del proyecto Maven de inscripción.
Haga clic para descargar el proyecto Maven de comprobaciones de seguridad.
Aplicaciones
Las aplicaciones de ejemplo están disponibles para iOS (Swift), Android, Cordova y Web.
- Haga clic para descargar el proyecto Cordova.
- Haga clic para descargar el proyecto iOS Swift.
- Haga clic para descargar el proyecto Android.
- Haga clic para descargar el proyecto de aplicación Web.
Uso de ejemplo
Siga el archivo README.md del ejemplo para obtener instrucciones.
▲Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.