Domanda

Diverso tra il nostro era in Dev e il nostro locale era

La nostra applicazione sta utilizzando la sicurezza a molla con la versione 3.1.0-release Spring.

Inizia in un file JSP, stiamo cercando di mostrare il nome utente connesso:

On Was in Dev, abbiamo un NoTreAdablePropertyException: "Principal Proprietà della proprietà di Bean non è leggibile o ha un metodo GETTER non valido: il tipo di ritorno del getter corrisponde al tipo di parametro del setter?"

Questo perché l'autenticazione sta usando un beanwrapper (beanwrapperimpl)

Alla riga 729 (primavera 3.1.0-release) di file beanwrapperimpl dell'errore è lanciato,

727:PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
728:if (pd == null || pd.getReadMethod() == null) {
729:                throw new NotReadablePropertyException(getRootClass(), this.nestedPath + propertyName);
730:}

Quindi PD è null o pd.getReadMethod () è nullo. In casi normali getReadMethod return Questo: Metodo oggetto [public java.lang.object org.springframework.security.authentication.usernamepasswordauthenticationToken.getPrincipal ()

aggiornareDopo il debug e l'aggiunta di alcuni registri in classe, sembra che "PD" sia nullo

Ho scritto questo codice in puro java per identificare l'errore

    logger.info(session.getAttribute("SPRING_SECURITY_CONTEXT").getClass().toString());
    final SecurityContextImpl sci = ((SecurityContextImpl) session.getAttribute("SPRING_SECURITY_CONTEXT"));
    logger.info(sci.getAuthentication().getClass().toString());
    final Authentication auth = sci.getAuthentication();
    logger.info(auth.getPrincipal().getClass().toString());
    final User u = (User) auth.getPrincipal();
    logger.info(u.getUsername());
    logger.info(SecurityContextHolder.getContext().getAuthentication().getName());

    logger.info("use beanWrapper :");
    final BeanWrapperImpl wrapper = new BeanWrapperImpl(auth);
    String property = "principal";
    Object result = wrapper.getPropertyValue(property);
    logger.info("property : " + property + " value :[" + result.toString() + "]");
    property = "principal.username";
    result = wrapper.getPropertyValue(property);
    logger.info("property : " + property + " value :[" + result.toString() + "]");

Log sul nostro era in Dev:

[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.context.SecurityContextImpl
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] class org.springframework.security.authentication.UsernamePasswordAuthenticationToken
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.userdetails.User
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] use beanWrapper :

<500 errore>

I registri sul nostro locale erano:

[2012-01-13 08:51:10,062] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.context.SecurityContextImpl
[2012-01-13 08:51:10,062] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] class org.springframework.security.authentication.UsernamePasswordAuthenticationToken
[2012-01-13 08:51:10,062] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.userdetails.User
[2012-01-13 08:51:10,062] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-13 08:51:10,073] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-13 08:51:10,073] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] use beanWrapper :
[2012-01-13 08:51:10,095] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] property : principal value :[org.springframework.security.core.userdetails.User@99ac08b4: Username: superadmin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SuperAdmin]
[2012-01-13 08:51:10,095] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] property : principal.username value :[superadmin]

Il nostro era in dev è una versione completa,

Il nostro locale era una versione di sviluppatore leggera e gratuita

AGGIORNARE

Dopo aver codificato una soluzione alternativa per ottenere il nome utente, il problema si verifica più lungo lungo la strada, ancora con BeingWrapperImpl

org.springframework.beans.NotReadablePropertyException: Invalid property 'codeAndName' of bean class [com.data.model.Country]: Bean property 'codeAndName' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:729)
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:721)
    at org.springframework.web.servlet.tags.form.OptionWriter.doRenderFromCollection(OptionWriter.java:216)
    at org.springframework.web.servlet.tags.form.OptionWriter.renderFromCollection(OptionWriter.java:186)
    at org.springframework.web.servlet.tags.form.OptionWriter.writeOptions(OptionWriter.java:139)
    at org.springframework.web.servlet.tags.form.OptionsTag.writeTagContent(OptionsTag.java:169)

AGGIORNARE 2 :

Il problema è più isolato: senza alcuna depazione alla sicurezza primaverile, solo Springmvc,

Quando A è stato messo in Beanwrapper non ha un setter corrispondente a getter, lancia una nonabilePropertyException solo su Was in Dev.

Quando c'è un setter, allora non c'è problema. Supponendo che la classe UsernamePasswordAuthenticationToken sia una classe di primavera. Classe.

È stato utile?

Soluzione

Una soluzione trovata:

Il problema è dovuto all'introduzione di ExtendedBeanInfo Inf Spring3.1

...

CF: https://github.com/springsource/spring-framework/commit/2f5085aef1e9ac3655a1b1250b6ceca9d0ca3398#diff-0

Quindi la soluzione è quella di prendere la versione precedente di CachedIntrospectionResults e inserirla nel pacchetto "org.springframework.beans" in modo che venga sovrascritto,

Ma devi essere sicuro che l'applicazione ClassPath sia per primo.

Altri suggerimenti

Stavo avendo lo stesso problema quando cercavo di impostare una proprietà nidificata usando BeanWrapper. Il problema era che la proprietà non aveva un setter, anche se non pensavo che il setter fosse necessario. L'aggiunta del setter ha risolto il mio problema. Grazie per aver fornito gli aggiornamenti Benoit! Il mio fagiolo:

public class Bean {
    private InnerBean innerBean = new InnerBean();
    public InnerBean getInnerBean() {
        return this.innerBean;
    }
}

Il mio codice beanwrapper che non ha fallito:

BeanWrapper wrapper = new BeanWrapperImpl(new Bean());
wrapper.setPropertyValue("innerBean.property","some value");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top