2016-02-11 45 views
0

我的J2E應用程序存在一個大問題。這是一個實現RESTFUL API的應用程序。我想插入一些安全認證,以區分普通用戶和管理員。在認證實施之前,@GET @ POST等方法是否奏效。這是我的供應商的代碼:如何實現提供者來創建認證

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package org.m2acsi.util; 

import java.lang.reflect.Method; 
import java.util.Arrays; 
import java.util.Base64; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 
import java.util.StringTokenizer; 
import javax.annotation.security.DenyAll; 
import javax.annotation.security.PermitAll; 
import javax.annotation.security.RolesAllowed; 
import javax.inject.Inject; 
import javax.ws.rs.NotAuthorizedException; 
import javax.ws.rs.container.ContainerRequestContext; 
import javax.ws.rs.container.ContainerRequestFilter; 
import javax.ws.rs.container.ResourceInfo; 
import javax.ws.rs.core.Context; 
import javax.ws.rs.core.MultivaluedMap; 
import javax.ws.rs.core.Response; 
import javax.ws.rs.ext.Provider; 
import org.m2acsi.boundary.AdminRessource; 
import org.m2acsi.entity.Admin; 

/** 
* 
* @author Michel 
*/ 
@Provider 
public class AutentificatorFilter implements ContainerRequestFilter{ 

private AdminRessource ressource; 

@Context 
private ResourceInfo resourceInfo; 
private static final String AUTORISATION="authorization", SCHEMA="Basic"; 
private static final Response ACCESS_DENIED= Response.status(Response.Status.UNAUTHORIZED).build(); 
private static final Response ACCESS_FORBIDEN= Response.status(Response.Status.FORBIDDEN).build(); 

@Override 
public void filter(ContainerRequestContext rc){ 
    Method method = resourceInfo.getResourceMethod(); 
    if (!method.isAnnotationPresent(PermitAll.class)){ //On teste si la méthode renvoyé (GET, POST...) est permise pour tous 
     if(method.isAnnotationPresent(DenyAll.class)){ //On teste si la méthode est interdite pour tous le monde, dans ce cas on refuse l'accès 
      rc.abortWith(ACCESS_FORBIDEN); 
      return; 
     } 
    } 
    final MultivaluedMap<String,String> headers = rc.getHeaders(); 
    final List<String> autorisation = headers.get(AUTORISATION); 
    if (autorisation == null || autorisation.isEmpty()){ 
     throw new NotAuthorizedException("BASIC realm=\"passport\""); 
    } 
    final String motdepasseencode = autorisation.get(0).replaceFirst(SCHEMA+" ",""); 
    String userplusmdp = new String(Base64.getDecoder().decode(motdepasseencode.getBytes())); 
    final StringTokenizer tokenizer = new StringTokenizer(userplusmdp,":"); 
    final String user = tokenizer.nextToken(); 
    final String mdp = tokenizer.nextToken(); 
    if (method.isAnnotationPresent(RolesAllowed.class)){ 
     RolesAllowed roles = method.getAnnotation(RolesAllowed.class); 
     Set<String> rolesSet = new HashSet<>(Arrays.asList(roles.value())); 
     if(!isUserAllowed(user,mdp,rolesSet)){ 
      rc.abortWith(ACCESS_DENIED); 
     } 
    } 
} 

//On test si l'utilisateur qui souhaite faire une demande particulière est bien admin 
private boolean isUserAllowed(final String user, final String mdp, final Set<String> roles){ 
    boolean isAllowed = false; 
    List<Admin> admin = this.ressource.getAll(); 
    String userRole = "ADMIN"; 
    for (Admin a : admin) { 
     if(user.equals(a.getLogin()) && mdp.equals(a.getMdp())){ 
      if(roles.contains(userRole)){ 
       isAllowed = true; 
       break; 
      } 
     } 
    } 
    return isAllowed; 
} 
} 

我型動物實體的代碼和ressources:

Demande:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package org.m2acsi.entity; 

import java.io.Serializable; 
import java.text.ParseException; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import javax.annotation.security.DeclareRoles; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 
import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.NamedQuery; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 
import javax.validation.constraints.Pattern; 
import org.m2acsi.util.TokenGenerator; 

/** 
* 
* @author Divi 
*/ 
@Entity 
@ManagedBean 
@ViewScoped 
@NamedQuery(name = "Demande.findAll", query = "SELECT d FROM Demande d") 
@Table(name = "DEMANDE") 
@DeclareRoles("ADMIN") 
public class Demande implements Serializable{ 

    @Id 
    @GeneratedValue 
    @Column 
    private long demande_id; 

    @Column 
    @Pattern(regexp ="^([a-z]+((|')[a-z]+)*)+([-]([a-z]+((|')[a-z]+)*)+)*$", 
      message ="Merci de saisir un nom valide") 
    private String nom; 

    @Column 
    @Pattern(regexp ="^([a-z]+((|')[a-z]+)*)+([-]([a-z]+((|')[a-z]+)*)+)*$", 
      message ="Merci de saisir un prénom valide") 
    private String prenom; 

    @Column 
    private String sexe; 

    @Column 
    @Pattern(regexp ="([a-zA-Z0-9 [-] ]*)", 
      message ="Merci de saisir un nom valide") 
    private String adresse; 

    @Column 
    private String num_pass; 

    @Column 
    private String pays; 

    @Column 
    @Pattern(regexp="^(0?[0-9]|[12][0-9]|3[01])/(0?[0-9]|1[012])/((?:19|20)[0-9]{2})$", 
      message ="Merci de saisir une date de naissance valide") 
    private String datenaiss; 

    @Column 
    private String delivrance; 

    @Column 
    private Date expiration; 

    @Column 
    private String statut; 

    @Column 
    private String token; 

    @OneToMany (cascade=CascadeType.ALL, mappedBy="demande") 
    private List<Action> actions = new ArrayList<>(); 

    public Demande() { 
    } 

    public Demande(String nom, String prenom, String sexe, 
      String adresse, String pays, String datenaiss) throws ParseException { 
     this.nom = nom; 
     this.prenom = prenom; 
     this.sexe = sexe; 
     this.adresse = adresse; 
     this.pays = pays; 
     this.datenaiss = datenaiss; 
     this.statut = "Début"; 
     this.delivrance = null; 
     this.expiration = null; 
     this.token = TokenGenerator.generateRandom(); 
    } 


    public long getId() { 
     return demande_id; 
    } 

    public void setId(long id) { 
     this.demande_id = id; 
    } 

    public String getStatut() { 
     return statut; 
    } 

    public void setStatut(String statut) { 
     this.statut = statut; 
    } 

    public List<Action> getActions() { 
     return actions; 
    } 

    public void setActions(List<Action> actions) { 
     this.actions = actions; 
    } 

    public String getNom() { 
     return nom; 
    } 

    public void setNom(String nom) { 
     this.nom = nom; 
    } 

    public String getPrenom() { 
     return prenom; 
    } 

    public void setPrenom(String prenom) { 
     this.prenom = prenom; 
    } 

    public String getSexe() { 
     return sexe; 
    } 

    public void setSexe(String sexe) { 
     this.sexe = sexe; 
    } 

    public String getAdresse() { 
     return adresse; 
    } 

    public void setAdresse(String adresse) { 
     this.adresse = adresse; 
    } 

    public String getPays() { 
     return pays; 
    } 

    public void setPays(String pays) { 
     this.pays = pays; 
    } 

    public String getDatenaiss() { 
     return datenaiss; 
    } 

    public void setDatenaiss(String datenaiss) { 
     this.datenaiss = datenaiss; 
    } 

    public String getDelivrance() { 
     return delivrance; 
    } 

    public void setDelivrance(String delivrance) { 
     this.delivrance = delivrance; 
    } 

    public Date getExpiration() { 
     return expiration; 
    } 

    public void setExpiration(Date expiration) { 
     this.expiration = expiration; 
    } 

    public void addAction(Action a) { 
     this.actions.add(a); 
    } 



} 

DemandeRessource:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package org.m2acsi.boundary; 

import java.util.List; 
import javax.annotation.security.DeclareRoles; 
import javax.ejb.Stateless; 
import javax.enterprise.event.Event; 
import javax.inject.Inject; 
import javax.persistence.EntityManager; 
import javax.persistence.EntityNotFoundException; 
import javax.persistence.PersistenceContext; 
import org.m2acsi.entity.Action; 
import org.m2acsi.entity.Demande; 

/** 
* 
* @author Divi 
*/ 
@DeclareRoles("ADMIN") 
@Stateless 
public class DemandeRessource { 

    @PersistenceContext 
    private EntityManager em; 

    @Inject 
    private Event<Demande> listener_d; 

    @Inject 
    private Event<Action> listener_a; 

    //GET ID 
    public Demande findById(long id) { 
     return this.em.find(Demande.class, id); 
    } 

    //GET ALL 
    public List<Demande> getAll() { 
     return this.em.createNamedQuery("Demande.findAll", Demande.class).getResultList(); 
    } 

    //GET STATUS 
    public List<Demande> findByStatus(String statut) { 
     return this.em.createQuery(
      "SELECT d FROM Demande d WHERE d.statut = ?1") 
      .setParameter(1, statut) 
      .getResultList(); 
    } 

    //GET ALL ACTIONS 
    public List<Action> getAllAction(Demande d) { 
     return this.em.createNamedQuery("Actions.findAll", Action.class) 
       .setParameter("demande_id", d.getId()) 
       .getResultList(); 
    } 

    //DELETE 
    public void delete(long id) { 
     try { 
      Demande d = this.em.getReference(Demande.class, id); 
      this.em.remove(d); 
     } catch (EntityNotFoundException e) {} 
    } 

    //POST Demande 
    public Demande saveDemande(Demande d) { 
     Demande dem = this.em.merge(d); 
     listener_d.fire(dem); 
     return dem; 
    } 

    //POST Action 
    public Action saveAction(Action a) { 
     Action act = this.em.merge(a); 
     listener_a.fire(act); 
     return act; 
    } 
} 

DemandeRepresentation:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package org.m2acsi.boundary; 

import java.net.URI; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.List; 
import javax.annotation.security.DeclareRoles; 
import javax.annotation.security.PermitAll; 
import javax.annotation.security.RolesAllowed; 
import javax.ejb.Stateless; 
import javax.inject.Inject; 
import javax.ws.rs.DELETE; 
import javax.ws.rs.GET; 
import javax.ws.rs.POST; 
import javax.ws.rs.PUT; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.Produces; 
import javax.ws.rs.QueryParam; 
import javax.ws.rs.core.Context; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 
import javax.ws.rs.core.UriInfo; 
import org.m2acsi.entity.Action; 
import org.m2acsi.entity.Demande; 
import org.m2acsi.entity.TypeAction; 

/** 
* 
* @author michel 
*/ 
@Stateless 
@Path("demandes") 
@DeclareRoles("ADMIN") 
public class DemandeRepresentation { 

    @Inject 
    private DemandeRessource ressource; 

    @GET // GET id 
    @Path("{id}") 
    @Produces({MediaType.APPLICATION_JSON}) 
    public Response findById(@PathParam("id") long id) { 
     Demande d = this.ressource.findById(id); 
     if (d != null) { 
      return Response.ok(d).build(); 
     } else { 
      return Response.status(Response.Status.NOT_FOUND).build(); 
     } 
    } 

    @GET 
    @Produces({MediaType.APPLICATION_JSON}) 
    @PermitAll 
    @RolesAllowed("ADMIN") 
    public List<Demande> findByStatus(@QueryParam("statut") String statut) { 
     if (statut == null) { 
      return this.ressource.getAll(); //Si pas de ?statut on getAll 
     } else { 
      return this.ressource.findByStatus(statut); //Si statut on findByStatut  
     } 
    } 

    @GET 
    @Produces({MediaType.APPLICATION_JSON}) //Get demandes/{id}/actions 
    @Path("{id}/actions") 
    public List<Action> findAllActionsByDemande(@PathParam("id") long id) { 
     Demande d = this.ressource.findById(id); 
     return d.getActions(); 
    } 

    @GET 
    @Produces({MediaType.APPLICATION_JSON}) //GET demandes/{id}/actions/{aid} 
    @Path("{id}/actions/{aid}") 
    public Action findActionById(@PathParam("id") long id, @PathParam("aid") int aid) { 
     Demande d = this.ressource.findById(id); 
     Action rep = null; 
     for (Action a : d.getActions()) { 
      if (a.getAid() == aid) { 
       rep = a; 
       break; 
      } 
     } 
     return rep; 
    } 

    @POST //POST demandes 
    public Response saveDemande(Demande d, @Context UriInfo uriInfo) { 
     d.setStatut("Début"); 
     Action a = new Action(TypeAction.ATTENTE_ATTRIBUTION, "Michel", "en cours"); 
     d.addAction(a); 
     Demande saved = this.ressource.saveDemande(d); 
     long idd = saved.getId(); 
     URI uri = uriInfo.getAbsolutePathBuilder().path("/" + idd).build(); 
     return Response.created(uri).build(); 
    } 

    @POST //POST demandes/{id}/actions 
    @Path("{id}/actions") 
    public Response saveAction(@PathParam("id") long id, Action a, @Context UriInfo uriInfo) { 
     Demande d = this.ressource.findById(id); 
     d.addAction(a); 
     Action saved = a; 
     SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy H:mm:ss"); 
     saved.setDate(formatter.format(new Date())); 
     saved = this.ressource.saveAction(a); 
     long idd = saved.getAid(); 
     URI uri = uriInfo.getAbsolutePathBuilder().path("/" + id +"actions/"+ idd).build(); 
     return Response.created(uri).build(); 
    } 

    @PUT 
    @Path("{id}") 
    public Demande updateDemande(@PathParam("id") long id, Demande d) { 
     d.setId(id); 
     return this.ressource.saveDemande(d); 
    } 

    @PUT 
    @Path("{id}/actions/{aid}") 
    public Action updateAction(@PathParam("id") long id, @PathParam("aid") int aid, Action a) { 
     a.setAid(aid); 
     SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy H:mm:ss"); 
     a.setDate(formatter.format(new Date())); 
     return this.ressource.saveAction(a); 
    } 

    @DELETE 
    @Path("{id}") 
    public void delete(@PathParam("id") long id) { 
     this.ressource.delete(id); 
    } 


} 

聯繫:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package org.m2acsi.entity; 

import java.io.Serializable; 
import javax.annotation.security.DeclareRoles; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.NamedQuery; 
import javax.persistence.Table; 

/** 
* 
* @author michel 
*/ 
@Entity 
@Table(name = "ADMIN") 
@NamedQuery(name="Admin.findAll", query="SELECT a FROM Admin a") 
@DeclareRoles("ADMIN") 
public class Admin implements Serializable{ 

    @Id 
    @Column(name = "LOGIN") 
    private String login; 

    @Column(name = "MDP") 
    private String mdp; //A crypter 

    public Admin(){} 

    public String getLogin() { 
     return login; 
    } 

    public void setLogin(String login) { 
     this.login = login; 
    } 

    public String getMdp() { 
     return mdp; 
    } 

    public void setMdp(String mdp) { 
     this.mdp = mdp; 
    } 

} 

AdminRessource:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package org.m2acsi.boundary; 

import java.util.List; 
import javax.annotation.security.DeclareRoles; 
import javax.ejb.Stateless; 
import javax.enterprise.event.Event; 
import javax.inject.Inject; 
import javax.persistence.EntityManager; 
import javax.persistence.EntityNotFoundException; 
import javax.persistence.PersistenceContext; 
import org.m2acsi.entity.Action; 
import org.m2acsi.entity.Admin; 

/** 
* 
* @author Divi 
*/ 
@DeclareRoles("ADMIN") 
@Stateless 
public class AdminRessource { 

    @PersistenceContext 
    private EntityManager em; 

    @Inject 
    private Event<Admin> listener; 

    //GET ALL 
    public List<Admin> getAll() { 
     List<Admin> admins = this.em.createNamedQuery("Admin.findAll", Admin.class).getResultList(); 
     System.out.println(admins.get(0).getLogin()); 
     return admins; 
    } 
} 

編輯:堆棧跟蹤的異常:

Avertissement: StandardWrapperValve[org.m2acsi.passport.JAXRSConfiguration]: Servlet.service() for servlet org.m2acsi.passport.JAXRSConfiguration threw exception 
java.lang.NullPointerException 
    at org.m2acsi.util.AutentificatorFilter.isUserAllowed(AutentificatorFilter.java:78) 
    at org.m2acsi.util.AutentificatorFilter.filter(AutentificatorFilter.java:69) 
    at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:132) 
    at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:68) 
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197) 
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:309) 
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) 
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267) 
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) 
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:298) 
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) 
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471) 
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) 
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) 
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206) 
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180) 
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) 
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111) 
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536) 
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571) 
    at java.lang.Thread.run(Thread.java:745) 

Infos: keepstate options resolved to true, saving appId 95366951280836608 for application passport. 
Infos: /file:/C:/Users/michel/Documents/NetBeansProjects/passport/passport/target/passport/WEB-INF/classes/_org.m2acsi_passport_war_1.0PU logout successful 
Grave: One cannot have more than one of @RolesAllowed, @PermitAll, @DenyAll in the same AnnotatedElement. 
symbol: METHOD location: public java.util.List org.m2acsi.boundary.DemandeRepresentation.findByStatus(java.lang.String) 

Grave: One cannot have more than one of @RolesAllowed, @PermitAll, @DenyAll in the same AnnotatedElement. 
symbol: METHOD location: public java.util.List org.m2acsi.boundary.DemandeRepresentation.findByStatus(java.lang.String) 

如果您有任何想法解決它,享受! 謝謝。

回答

0

我發現了這個問題的解決方案。爲了詢問我的數據庫以知道哪些人可以訪問我的資源,有必要在我的類AutentificatorFilter的AdminRessource屬性之前添加@EJB註釋。