Risultati da 1 a 14 di 14
  1. #1
    La Nebbia
    Data Registrazione
    27-03-13
    Messaggi
    7

    Predefinito Spring Security+hibernate

    Buon pomeriggio,
    sono una studentessa di informatica e sto cercando di imparare Spring Security per un piccolo sistema di login.
    Purtroppo ho un problema che non riesco a risolvere.

    all'interno del mio progetto ho due classi SpringSecurityContext e UserSession che vengono utilizzate dalle classi LoginService e LoginController per effettuare tutte le operazioni di login.

    la classe SpringSecurity è:

    Codice:
    public class SpringSecurityContext
    
    {    public static UserSession getUser(final HttpSession httpSession)   
     {    
        SecurityContext securityContext = (SecurityContext) httpSession.getAttribute("SPRING_SECURITY_CONTEXT");        
    if (securityContext != null)    
        {    
            return (UserSession) securityContext.getAuthentication().getPrincipal();        }      
      else        {            securityContext = SecurityContextHolder.getContext();          
      return (UserSession)securityContext.getAuthentication().getPrincipal();        } 
       }    public static void removeUser(final HttpSession httpSession)    {        final SecurityContext securityContext = (SecurityContext) httpSession.getAttribute("SPRING_SECURITY_CONTEXT");        if (securityContext != null)        {            securityContext.setAuthentication(null);        }        else        {            SecurityContextHolder.getContext().setAuthentication(null);        }    }    public static void setDefaultUser(final HttpSession httpSession)    {        final UserSession userSession = new UserSession();        final UsernamePasswordAuthenticationToken authenticate = new UsernamePasswordAuthenticationToken(userSession,                userSession.getPassword());        SecurityContext securityContext = (SecurityContext) httpSession.getAttribute("SPRING_SECURITY_CONTEXT");        if (securityContext != null)        {            securityContext.setAuthentication(authenticate);        }        else        {            securityContext = SecurityContextHolder.getContext();            securityContext.setAuthentication(authenticate);            httpSession.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);        }    }    public static void setUser(final HttpSession httpSession, final User user)    {        final UsernamePasswordAuthenticationToken authenticate = new UsernamePasswordAuthenticationToken(user, user.getPassword());        SecurityContext securityContext = (SecurityContext) httpSession.getAttribute("SPRING_SECURITY_CONTEXT");        if (securityContext != null)        {            securityContext.setAuthentication(authenticate);        }        else        {            securityContext = SecurityContextHolder.getContext();            securityContext.setAuthentication(authenticate);            httpSession.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);        }    } }
    



    la classe User Session è:

    Codice:
    public class UserSession extends User implements Serializable {
    
        private static final long serialVersionUID = 1L;        /**         * campi di User     *      * l'username dell’utente     * la sua password     * (booleano) utente abilitato     * (booleano) account non scaduto     *  (booleano) credenziali non scadute     *  (booleano) account non bloccato     *   Lista di permessi di tipi GrantedAuthorities        */        public static enum Stato {VISITATORE, REGISTRATO, CONFERMATO, LOGGED};    public static enum Errors {ERROR_USER_PASSWORD, ERROR_INVALID_STATE, ERROR_EXIST_MAIL};    private boolean complete;    private Stato stato;    private String nome;    private Errors error;    private Long id;        public UserSession()    {        super("username", "password", false, false, false, false, new HashSet<GrantedAuthority>());                stato = Stato.VISITATORE;    }    public UserSession(String username, String password, boolean enabled,            boolean accountNonExpired, boolean credentialsNonExpired,            boolean accountNonLocked, Collection<GrantedAuthority> authorities)     {        super(username, password, enabled, accountNonExpired, credentialsNonExpired,                accountNonLocked, authorities);        // TODO Auto-generated constructor stub    }    public UserSession(String username, String password, boolean enabled,            boolean accountNonExpired, boolean credentialsNonExpired,            boolean accountNonLocked, Collection<GrantedAuthority> authorities,            String nome, Errors error, Long id)     {        super(username, password, enabled, accountNonExpired, credentialsNonExpired,                accountNonLocked, authorities);        this.stato = stato;        this.nome = nome;        this.error = error;        this.id = id;    }    public Stato getStato() {        return stato;    }    public void setStato(Stato stato) {        this.stato = stato;    }        public String getNome() {        return nome;    }    public void setNome(String nome) {        this.nome = nome;    }    public Errors getError() {        return error;    }    public void setError(Errors error) {        this.error = error;    }    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public boolean isComplete() {        return complete;    }    public void setComplete(boolean complete) {        this.complete = complete;    }     }
    
    



    l'errore all'esecuzione è:

    SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/UtenteVoli] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: java.lang.String cannot be cast to esempio.service.UserSession] with root cause
    java.lang.ClassCastException: java.lang.String cannot be cast to esempio.service.UserSession
    at esempio.service.SpringSecurityContext.getUser(Spri ngSecurityContext.java:26)
    at esempio.service.LoginService.service(LoginService. java:1
    at esempio.web.LoginController.login(LoginController. java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.web.bind.annotation.support.Ha ndlerMethodInvoker.doInvokeMethod(HandlerMethodInv oker.java:710)
    at org.springframework.web.bind.annotation.support.Ha ndlerMethodInvoker.invokeHandlerMethod(HandlerMeth odInvoker.java:167)
    at org.springframework.web.servlet.mvc.annotation.Ann otationMethodHandlerAdapter.invokeHandlerMethod(An notationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.mvc.annotation.Ann otationMethodHandlerAdapter.handle(AnnotationMetho dHandlerAdapter.java:402)
    at org.springframework.web.servlet.DispatcherServlet. doDispatch(DispatcherServlet.java:771)
    at org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:716)
    at org.springframework.web.servlet.FrameworkServlet.p rocessRequest(FrameworkServlet.java:647)
    at org.springframework.web.servlet.FrameworkServlet.d oGet(FrameworkServlet.java:552)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:72
    at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 343)
    at org.springframework.security.web.access.intercept. FilterSecurityInterceptor.invoke(FilterSecurityInt erceptor.java:109)
    at org.springframework.security.web.access.intercept. FilterSecurityInterceptor.doFilter(FilterSecurityI nterceptor.java:83)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.access.ExceptionT ranslationFilter.doFilter(ExceptionTranslationFilt er.java:97)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.session.SessionMa nagementFilter.doFilter(SessionManagementFilter.ja va:100)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.authentication.An onymousAuthenticationFilter.doFilter(AnonymousAuth enticationFilter.java:7
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.servletapi.Securi tyContextHolderAwareRequestFilter.doFilter(Securit yContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.savedrequest.Requ estCacheAwareFilter.doFilter(RequestCacheAwareFilt er.java:35)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.authentication.Ab stractAuthenticationProcessingFilter.doFilter(Abst ractAuthenticationProcessingFilter.java:18
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.authentication.lo gout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.context.SecurityC ontextPersistenceFilter.doFilter(SecurityContextPe rsistenceFilter.java:79)
    at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java: 355)
    at org.springframework.security.web.FilterChainProxy. doFilter(FilterChainProxy.java:149)
    at org.springframework.web.filter.DelegatingFilterPro xy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterPro xy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invo ke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invo ke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBas e.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke( StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(A ccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invok e(StandardEngineValve.java:11
    at org.apache.catalina.connector.CoyoteAdapter.servic e(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.p rocess(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnect ionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProce ssor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker( ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

    Qualcuno può essermi di aiuto?????...
    in pratica mi dice che il cast (UserSession)securityContext.getAuthentication().g etPrincipal();
    non può essere fatto...
    ma perchè???
    come posso risolere???

    vi ringrazio in anticipo!!!!

  2. #2
    La Nebbia
    Data Registrazione
    27-03-13
    Messaggi
    7

    Predefinito Re: Spring Security+hibernate

    per puntualizzare,
    la funzione GetPrincipal()
    restituisce un Object
    e poi faccio il cast a UserSession

  3. #3
    Lo Zio
    Data Registrazione
    23-06-08
    Località
    Valle d'Agno
    Messaggi
    2,222

    Predefinito Re: Spring Security+hibernate

    utilizza pastebin(http://pastebin.com/), la prossima volta, perché è illeggibile quanto hai postato.

    Tornando al codice, il fatto che restituisca Object, in Java, vuol dire tutto e niente, perché Object è superclasse di tutte le classi.
    Nell'eccezione si legge dalla prima riga che tu vuoi fare il cast di una String a UserSession, indicando che il tipo dell'oggetto restituito da getPrincipal() in fase di esecuzione è stringa. Perché questo accade non lo so, non uso spring e tanto meno hibernate, però facendo una rapida ricerca sembra che getPrincipal ritorni una stringa nel caso in cui si sia fatta una autenticazione con username e password e quanto ti ritorna è l'username.

    La risoluzione di questo problema dipende da cosa volevi fare con l'oggetto UserSession... se proprio ti serve quell'oggetto dovrai probabilmente cambiare sistema di autenticazione o capire se puoi prenderlo/crearlo da qualche altra parte...

  4. #4
    Il Puppies L'avatar di MscG
    Data Registrazione
    15-09-01
    Località
    Monti abruzzesi
    Messaggi
    777

    Predefinito Re: Spring Security+hibernate

    Potresti postare anche la configurazione xml dei bean di Spring Security?

    Comunque, Spring Security usa 3 classi per gestire l'autenticazione:
    un AuthenticationManager che dipende da uno o più AuthenticationProvider ai quali delega il compito di autenticare l'utente con i dati forniti nella maschera di login. Generalmente, ma dipende dall'implementazione, gli AuthenticationProvider delegano ad un oggetto di tipo UserDetailsService il compito di ritrovare un oggetto "utente" a partire dallo username.
    Evidentemente nella tua configurazione stai usando un AuthenticationProvider che restituisce un oggetto Authentication il cui principal è solo un oggetto stringa e non uno UserSession.

    Una configurazione tipo è questa qui:

    Codice:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans:beans xmlns="http://www.springframework.org/schema/security"
        xmlns:beans="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <global-method-security secured-annotations="enabled" />
    
        <http auto-config="true" use-expressions="true">
            <!-- Don't set any role restrictions on the following -->
            <intercept-url pattern="/" access="permitAll" />
            <intercept-url pattern="/index.*" access="permitAll" />
            <intercept-url pattern="/login" access="permitAll" />
            <intercept-url pattern="/resources/**" access="permitAll" />
            
            <!-- Restrict access to ALL other pages -->
            <intercept-url pattern="/**" access="isAuthenticated() and hasRole('ROLE_USER')" />
    
            <!-- Set the login page and what to do if login fails -->
            <form-login login-page="/" authentication-failure-url="/login?login_error=true" default-target-url="/login" />
            <logout logout-success-url="/" />
        </http>
        
        <beans:bean id="usersData" class="it.tgmonline.users.MyUserDetailsService">
        </beans:bean>
    
        <beans:bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
            <beans:property name="userDetailsService" ref="usersData" />
        </beans:bean>
        
        <authentication-manager alias="authenticationManager">
            <authentication-provider ref="authenticationProvider" />
        </authentication-manager>
    </beans:beans>
    Dove it.tgmonline.users.MyUserDetailsService implementa l'interfaccia org.springframework.security.core.userdetails.User DetailsService e restituisce il tuo oggetto UserSession (che già estende User che implementa UserDetails).

    Ah, per ottenere l'utente attualmente loggato ti consiglio di usare questo snippet di codice:
    Codice:
    public static UserDetails getActualLoggedUser() {
        UserDetails loggedUser = null;
        try {
            loggedUser = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        } catch (Exception e) { }
        return loggedUser;
    }
    Ultima modifica di MscG; 29-03-13 alle 09:13:21

  5. #5
    La Nebbia
    Data Registrazione
    27-03-13
    Messaggi
    7

    Predefinito Re: Spring Security+hibernate

    Vi ringrazio per i consigli....
    ho cambiato del tutto il progetto grazie ai vostri suggerimenti...
    purtroppo adesso ho un altro piccolo problema...
    praticamente la mia pagina di login non funziona come dovrebbe...
    L'utente esiste nel database e userDetailsService me lo trova ma vengo sempre reindirizzata nella pagina di login con un errore...

    il mio file application-springsecurity.xml è:

    Codice:
    <beans:beans xmlns="http://www.springframework.org/schema/security"
        xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
            xmlns:security="http://www.springframework.org/schema/security"
            xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:p="http://www.springframework.org/schema/p" 
        xmlns:tx="http://www.springframework.org/schema/tx"
        
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/security 
                http://www.springframework.org/schema/security/spring-security-3.0.xsd
                http://www.springframework.org/schema/mvc 
                http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
                http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    
    
    
    
    <!-- A custom service where Spring will retrieve users and their corresponding access levels  -->
        <beans:bean id="customUserDetailsService" class="main.esempio.service.CustomUserDetailsService"/>
        
    
    
    
    
        
    <security:http auto-config="true" use-expressions="true" access-denied-page="/denied" >
        
            <security:intercept-url pattern="/login" access="permitAll"/>
            <security:intercept-url pattern="/common" access="hasRole('ROLE_USER')"/>
            
            <security:form-login
                    login-page="/login" 
                    authentication-failure-url="/login?error=true" 
                    default-target-url="/common"
                    login-processing-url="/j_spring_security_check"/>
                
            <security:logout 
                    invalidate-session="true" 
                    logout-success-url="/login" 
                    logout-url="/logout"/>
        
        </security:http>
        
        <!-- Declare an authentication-manager to use a custom userDetailsService -->
        <security:authentication-manager>
                <security:authentication-provider user-service-ref="customUserDetailsService">
                        <security:password-encoder ref="passwordEncoder"/>
                </security:authentication-provider>
        </security:authentication-manager>
        
        <!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database -->
        <beans:bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
    
    
     
          
        <!-- Activates various annotations to be detected in bean classes -->
        <context:annotation-config />
        
        <!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
         For example @Controller and @Service. Make sure to set the correct base-package-->
        <context:component-scan base-package="main.esempio" />
        
            
    </beans:beans>
    la classe che implementa userDetailsService è:

    Codice:
    package main.esempio.service;
    
    
    
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    
    import main.esempio.dominio.Utenti;
    
    
    
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.dao.DataAccessException;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.GrantedAuthorityImpl;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    
    import main.esempio.dao.UtentiDAO;
    
    
    /**
     * A custom service for retrieving users from a custom datasource, such as a database.
     * <p>
     * This custom service must implement Spring's {@link UserDetailsService}
     */
    @Service
    @Transactional
    public class CustomUserDetailsService implements UserDetailsService {
        
    
    
        @Autowired
        private UtentiDAO userDAO ;
        
        /**
         * Retrieves a user record containing the user's credentials and access. 
         */
    
    
        
        /**
         * Retrieves the correct ROLE type depending on the access level, where access level is an Integer.
         * Basically, this interprets the access value whether it's for a regular user or admin.
         * 
         * @param access an integer value representing the access of the user
         * @return collection of granted authorities
         */
         public Collection<GrantedAuthority> getAuthorities(Integer access) 
         {
             System.out.println("sono in getAutority");
                // Create a list of grants for this user
                List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(2);
                
                // All users are granted with ROLE_USER access
                // Therefore this user gets a ROLE_USER by default
                authList.add(new GrantedAuthorityImpl("ROLE_USER"));
                
                // Check if this user has admin access 
                // We interpret Integer(1) as an admin user
                if ( access.compareTo(1) == 0) {
                    // User has admin access
                    authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
                }
    
    
                // Return list of granted authorities
                return authList;
          }
    
    
        @Override
        public UserDetails loadUserByUsername(String username)
                throws UsernameNotFoundException, DataAccessException
                {
            System.out.println("sono in loadUserByUsername ");
            // TODO Auto-generated method stub
            // Declare a null Spring User
                    UserDetails user = null;
                    
                    try {
                        
                        // Search database for a user that matches the specified username
                        // You can provide a custom DAO to access your persistence layer
                        // Or use JDBC to access your database
                        // DbUser is our custom domain user. This is not the same as Spring's User
                        Utenti utenti = userDAO.findUtente(username);
                        // Populate the Spring User object with details from the dbUser
                        // Here we just pass the username, password, and access level
                        // getAuthorities() will translate the access level to the correct role type
                        System.out.println("sono nel try");
                        user =  new User(
                                utenti.getUtentiName(), 
                                utenti.getPassword().toLowerCase(),
                                true,
                                true,
                                true,
                                true,
                                getAuthorities(utenti.getAccess()) );
                        
    
    
                    } catch (Exception e) {
                        throw new UsernameNotFoundException("Error in retrieving user");
                    }
                    
                    // Return user to Spring for processing.
                    // Take note we're not the one evaluating whether this user is authenticated or valid
                    // We just merely retrieve a user that matches the specified username
                    System.out.println("ritorno l'utente trovato");
                    System.out.println("l'utente trovato ha autority"+user.getAuthorities().toString());
                    return user;
        }
    }
    e il mio login logout controller è:

    Codice:
    package main.esempio.controller;
    
    
    
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    
    /**
     * Handles and retrieves the login or denied page depending on the URI template
     */
    @Controller
    public class LoginLogoutController {
            
    
    
        /**
         * Handles and retrieves the login JSP page
         * 
         * @return the name of the JSP page
         */
        @RequestMapping(value = "login", method = RequestMethod.GET)
        public String getLoginPage(@RequestParam(value="error", required=false) boolean error, 
                ModelMap model) {
    
    
            // Add an error message to the model if login is unsuccessful
            // The 'error' parameter is set to true based on the when the authentication has failed. 
            // We declared this under the authentication-failure-url attribute inside the spring-security.xml
            /* See below:
             <form-login 
                    login-page="/auth/login" 
                    authentication-failure-url="/auth/login?error=true" 
                    default-target-url="/main/common"/>
             */
            //System.out.println("l'errore è "+logger.getAdditivity());
            System.out.println("sono in loginlogoutController ");
            
            System.out.println("il modello è"+model.toString());
            if (error == true) {
                //logger.setAdditivity(false);    
                System.out.println("l'errore c'è");
                // Assign an error message
                model.put("error", "Utente non valido Riprovare");
            } else {
                System.out.println("non c'è errore");
                model.put("error", "");
                //return "common";
            }
            System.out.println("ritorno login");
            // This will resolve to /WEB-INF/jsp/loginpage.jsp
            return "login";
        }
    
    
        
        
        /**
         * Handles and retrieves the denied JSP page. This is shown whenever a regular user
         * tries to access an admin only page.
         * 
         * @return the name of the JSP page
         */
        @RequestMapping(value = "denied", method = RequestMethod.GET)
         public String getDeniedPage() {
            
            System.out.println("sono in denied e ritorno denied");
            // This will resolve to /WEB-INF/jsp/deniedpage.jsp
            return "deniedpage";
        }
    }
    qualcuno mi sa spiegare perchè non entro mai in /common e vado sempre in authentication-failure-url="/login?error=true" ????

  6. #6
    Il Puppies L'avatar di MscG
    Data Registrazione
    15-09-01
    Località
    Monti abruzzesi
    Messaggi
    777

    Predefinito Re: Spring Security+hibernate

    Allora, prima di tutto un consiglio spassionato:
    NON usare le System.out per stampare i messaggi di stato dell'applicazione!
    Inserisci nel tuo progetto il jar di log4j (non so se usi Maven per gestire le dipendenze o se lo fai a mano) e usa il file log4j.xml o log4j.properties per configurare i logger.
    Spring già di suo usa Commons Logging, che è un sistema di interfacce che serve a wrappare vari sistemi di logging: praticamente, se trova log4j nel classpath, Commons Logging redirigerà verso di esso tutte le operazioni di scrittura di log. Se imposti a DEBUG il livello di logging di Spring Security ti dirà cosa è andato male nel processo di login.
    Ti posto un esempio di log4j.xml. Questo file dovrà andare a finire nella cartella WEB-INF/classes del tuo war:

    Codice:
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
        <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
            <param name="File" value="application.log"/>
            <param name="MaxFileSize" value="2MB"/>
            <param name="MaxBackupIndex" value="10"/>
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%d %5p [%30.30c] %m%n"/>
            </layout>
        </appender>
    
        <appender name="SPRING" class="org.apache.log4j.RollingFileAppender">
            <param name="File" value="application-spring.log"/>
            <param name="MaxFileSize" value="2MB"/>
            <param name="MaxBackupIndex" value="3"/>
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%d %5p [%30.30c] %m%n"/>
            </layout>
        </appender>
    
        <logger name="my.application">
            <level value="debug"/>
        </logger>
    
        <logger name="org.springframework.security" additivity="false">
            <level value="debug"/>
            <appender-ref ref="SPRING"/>
        </logger>
    
        <root>
            <priority value="error"/>
            <appender-ref ref="FILE"/>
        </root>
    
    </log4j:configuration>
    In pratica, con questo file crei due appender chiamati FILE e SPRING. Il primo scriverà nel file application.log, il secondo nel file application-spring.log, formattando i messaggi secondo il formato specificato nel parametro ConversionPattern (qui trovi più dettagli). Dopo di che vengono creati tre logger:
    1. Il primo verrà applicato a tutte le classi che si trovano sotto il package my.application, a qualunque livello di annidamento (anche, ad esempio, a my.application.another.package.MyClass) che imposta come livello soglia DEBUG;
    2. Il secondo che si applica al package org.springframework.security ed imposta come livello soglia DEBUG e specifica che i messaggi dovranno essere accodati solo all'appender SPRING;
    3. Il terzo, il root, specifica che l'appender di default è FILE ed il livello soglia è ERROR.
    Per usare i logger, puoi modificare ad esempio la tua classe CustomUserDetailsService in questo modo:
    Codice:
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    
    import main.esempio.dominio.Utenti;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.dao.DataAccessException;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.GrantedAuthorityImpl;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    
    import main.esempio.dao.UtentiDAO;
    
    
    /**
     * A custom service for retrieving users from a custom datasource, such as a database.
     * <p>
     * This custom service must implement Spring's {@link UserDetailsService}
     */
    @Service
    @Transactional
    public class CustomUserDetailsService implements UserDetailsService {
        
        private static final Log LOG = LogFactory.getLog(CustomUserDetailsService.class);
    
        @Autowired
        private UtentiDAO userDAO ;
        
        /**
         * Retrieves a user record containing the user's credentials and access. 
         */
    
    
        
        /**
         * Retrieves the correct ROLE type depending on the access level, where access level is an Integer.
         * Basically, this interprets the access value whether it's for a regular user or admin.
         * 
         * @param access an integer value representing the access of the user
         * @return collection of granted authorities
         */
         public Collection<GrantedAuthority> getAuthorities(Integer access) 
         {
             LOG.debug("sono in getAutority");
                // Create a list of grants for this user
                List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(2);
                
                // All users are granted with ROLE_USER access
                // Therefore this user gets a ROLE_USER by default
                authList.add(new GrantedAuthorityImpl("ROLE_USER"));
                
                // Check if this user has admin access 
                // We interpret Integer(1) as an admin user
                if ( access.compareTo(1) == 0) {
                    // User has admin access
                    authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
                }
    
    
                // Return list of granted authorities
                return authList;
          }
    
    
        @Override
        public UserDetails loadUserByUsername(String username)
                throws UsernameNotFoundException, DataAccessException
                {
            LOG.debug("sono in loadUserByUsername ");
            // TODO Auto-generated method stub
            // Declare a null Spring User
                    UserDetails user = null;
                    
                    try {
                        
                        // Search database for a user that matches the specified username
                        // You can provide a custom DAO to access your persistence layer
                        // Or use JDBC to access your database
                        // DbUser is our custom domain user. This is not the same as Spring's User
                        Utenti utenti = userDAO.findUtente(username);
                        // Populate the Spring User object with details from the dbUser
                        // Here we just pass the username, password, and access level
                        // getAuthorities() will translate the access level to the correct role type
                        LOG.debug("sono nel try");
                        user =  new User(
                                utenti.getUtentiName(), 
                                utenti.getPassword().toLowerCase(),
                                true,
                                true,
                                true,
                                true,
                                getAuthorities(utenti.getAccess()) );
                        
    
    
                    } catch (Exception e) {
                        throw new UsernameNotFoundException("Error in retrieving user");
                    }
                    
                    // Return user to Spring for processing.
                    // Take note we're not the one evaluating whether this user is authenticated or valid
                    // We just merely retrieve a user that matches the specified username
                    LOG.debug("ritorno l'utente trovato");
                    LOG.debug("l'utente trovato ha autority"+user.getAuthorities().toString());
                    return user;
        }
    }
    L'oggetto di tipo Log ha vari metodi (trace, debug, info, warn, error, fatal) per inviare messaggi di logging a diversi livelli di importanza crescente. Modificando la configurazione di log4j puoi, senza dover cambiare nulla nel tuo codice, rendere più o meno verboso il log dell'applicazione, oltre a poter attivare i messaggi di logging delle librerie che usi (come spring security, in questo caso).

    Ah, se preferisci i messaggi di logging in console, puoi sempre usare il ConsoleAppender al posto del RollingFileAppender nella configurazione di log4j!

  7. #7
    Shogun Assoluto L'avatar di Sticky©
    Data Registrazione
    09-08-04
    Località
    Roma
    Messaggi
    36,491

    Predefinito Re: Spring Security+hibernate

    Non sarebbe preferibile tenere la configurazione del log4j fuori dal war? Tipo nella conf di jboss...
    Almeno se deve modificare la verbosity o aggiungere categorie o appender non deve aprirsi ogni volta il war.

  8. #8
    Il Puppies L'avatar di MscG
    Data Registrazione
    15-09-01
    Località
    Monti abruzzesi
    Messaggi
    777

    Predefinito Re: Spring Security+hibernate

    Se il file sta nella root del classpath, log4j si auto-configura, altrimenti gli va detto a mano come configurarsi. Se usa jboss può evitare di mettere il jar di log4j e configurare il logger tramite console jmx ma mi pareva un po' troppo fuori argomento!

    Inviato dal mio GT-I9100P con Tapatalk 2

  9. #9
    La Nebbia
    Data Registrazione
    27-03-13
    Messaggi
    7

    Predefinito Re: Spring Security+hibernate

    vi ringrazio per i consigli...
    ho risolto il problema togliendo queste due righe di codice...
    Codice:
    <security:password-encoder ref="passwordEncoder"/>
    
    <beans:bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
    adesso ho un altro piccolissimo problema che non riesco proprio a capire....
    io ho due classi mappate con hibernate che sono Utenti e Voli...
    Le due classi hanno una relazione molti a molti che fa sì che hibernate costruisca la tabella Utenti_Voli che in pratica mi tiene conto delle prenotazioni degli utenti.

    Quindi, quando vado a fare una nuova prenotazione faccio questo:

    Codice:
                      Set<Voli> v =  new HashSet<Voli>(0);
    		 v.add(voli);
    		user.setVoli(v);
    		sessionFactory.getCurrentSession().saveOrUpdate(user);
    il tutto funziona solo per la prima prenotazione.
    Quando metto una seconda prenotazione hibernate mi cancella la prima...
    ma perchè????
    le operazioni che hibernate fa le stampo a video e sono:

    UPDATE su Utenti
    DELETE su Utenti_Voli
    INSERT su Utenti_Voli

    perchè fa questa delete?????

    qualcuno me lo spiega???

    help me!!!!

  10. #10
    Il Puppies L'avatar di MscG
    Data Registrazione
    15-09-01
    Località
    Monti abruzzesi
    Messaggi
    777

    Predefinito Re: Spring Security+hibernate

    Il problema sta qui:

    Codice:
    user.setVoli(v);
    Dove v è un HashSet che contiene solo il nuovo elemento voli. In questo modo stai rimuovendo completamente tutte le vecchie associazioni utente-voli e le stai sostituendo con questo nuovo set. Quando fai il saveOrUpdate ovviamente Hibernate va a riflettere lo stato dell'oggetto user sul DB, ovvero lo associerà solo al volo voli. Prova così:

    Codice:
    if(user.getVoli() == null)
        user.setVoli(new LinkedHashSet<Voli>());
    user.getVoli().add(voli);
    sessionFactory.getCurrentSession().saveOrUpdate(user);
    In questo modo crei il set solo se necessario e, nel caso il cui questo sia già presente, aggiungi il nuovo elemento alla collection già presente.

  11. #11
    La Nebbia
    Data Registrazione
    27-03-13
    Messaggi
    7

    Predefinito Re: Spring Security+hibernate

    hai perfettamente ragione....
    purtroppo però mi da un errore la riga
    Codice:
    			user.getVoli().add(voli);
    l'errore è:
    Codice:
    SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/Utenti] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: main.esempio.dominio.Utenti.voli, no session or session was closed] with root cause
    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: main.esempio.dominio.Utenti.voli, no session or session was closed
    	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
    	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
    	at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
    	at org.hibernate.collection.PersistentSet.add(PersistentSet.java:212)
    	at main.esempio.dao.PrenotaDAOImpl.saveUtenti(PrenotaDAOImpl.java:45)
    hai qualche idea su questo errore?

  12. #12
    Il Puppies L'avatar di MscG
    Data Registrazione
    15-09-01
    Località
    Monti abruzzesi
    Messaggi
    777

    Predefinito Re: Spring Security+hibernate

    Purtroppo... sì, conosco la ragione del problema!

    Tutto nasce dalla particolare strategia di caricamento lazy adottato di default da Hibernate quando si hanno relazioni 1..n o n..n: in pratica per costruire completamente il tuo bean di tipo Utenti, che ha un riferimento ad un set di oggetti di tipo Voli, Hibernate dovrebbe eseguire due query, la prima che carica i campi propri dell'oggetto utente e la seconda che carica le righe con i dati dei voli, per poi trasformare tutte queste righe in oggetti da salvare in RAM. Ora, è facile capire che tutto ciò è solo uno spreco di tempo e memoria se tu alla lista dei voli non devi accedere! Pertanto Hibernate di default ti carica solo i dati propri dell'utente e, nel set che contiene i voli, inserisce una collection "finta" che viene riempita solo la prima volta che cerchi di accederci realmente (nel tuo caso tramite il metodo add), da qui il termine lazy loading.

    Ora, che significa l'eccezione che hai ottenuto? In pratica il messaggio "no session or session was closed" indica che la transazione che ha caricato l'utente ed è stata associata alla collection finta è terminata e pertanto l'esecuzione della query che dovrebbe riempire la collection con i voli è fallita. Per risolvere il problema devi prima eseguire un merge dell'utente, ovvero devi riassociarlo ad una nuova transazione, più o meno in questo modo:
    Codice:
    @Transactional
    public void aggiornaUtente(Utenti user, Voli voli) {
        sessionFactory.getCurrentSession().merge(user);
        if(user.getVoli() == null)
            user.setVoli(new LinkedHashSet<Voli>());
        user.getVoli().add(voli);
        sessionFactory.getCurrentSession().saveOrUpdate(user);
    }
    Questo codice l'ho scritto a memoria quindi prendilo con le pinze!

    Un'altra soluzione è di far caricare in memoria anche la lista dei voli, aggirando la lazyness. In questo caso devi modificare il metodo loadUserByUsername cambiando la riga che fa la find con queste due righe:
    Codice:
    Utenti utenti = userDAO.findUtente(username);
    utenti.getVoli().size();
    L'accesso al metodo size della collection dei voli obbliga Hibernate ad eseguire la query di caricamento dei bean collegati, pertanto in memoria non troverai più la collection finta, ma i dati dei voli veri e propri.
    Ultima modifica di MscG; 06-04-13 alle 16:09:11

  13. #13
    La Nebbia
    Data Registrazione
    27-03-13
    Messaggi
    7

    Predefinito Re: Spring Security+hibernate

    grazie mille per la risposta!!!!!!...
    adesso funziona il tutto.....
    avrei però un altra domanda da fare...

    ho la mia jsp che mi fa vedere i voli disponibili e se clicco su un volo posso prenotarlo...

    questa è la mia jsp:

    Codice:
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
        <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Lista Voli</title>
    </head>
    <body>
    
    
    <hr>
    Username : ${user} <br/>
    <br/>
    <br/>
    <br/>
    
    
    <a href="voli" >TORNA ALLA LISTA DEI VOLI DISPONIBILI  </a><br></br>
    
    
    <a href="logout" >LOGOUT  </a><br></br>
    <fieldset>
    <legend>Prenota i voli cliccando sul nome</legend>
    <c:forEach items="${voli}" var="v">
        <a href='<c:url value="prenota/${v.voliName}"/>'>Nome: <c:out value="${v.voliName}" /></a><br/><br/>
        Partenza: <c:out value="${v.voliPartenza}" /><br/><br/>
        Destinazione: <c:out value="${v.voliDestinazione}" /><br/><br/>
        <hr/>
    </c:forEach>
    </fieldset>
    
    
    </body>
    </html>


    il mio controller è:

    Codice:
    
    package main.esempio.controller;
    
    
    import java.security.Principal;
    
    
    import main.esempio.dao.PrenotaDAO;
    import main.esempio.dao.UtentiDAO;
    import main.esempio.dao.VoliDAO;
    import main.esempio.dominio.Utenti;
    import main.esempio.dominio.Voli;
    import main.esempio.service.*;
    
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.SessionAttributes;
    
    
    @Controller
    
    
    public class  PrenotaController {
    
    
        @Autowired
        private PrenotaDAO prenotaDao;
        @Autowired
        private UtentiDAO utentiDao;
        @Autowired
        private VoliDAO voliDao;
    
    
        
        
        
         @RequestMapping(value = "/prenota/{nameVoli}", method = RequestMethod.GET)
            public String edit(@PathVariable String nameVoli, Model model,Principal principal)
         {
        
            
            try {
                 Voli v=voliDao.findVoli(nameVoli);
                 Utenti u;
                u = utentiDao.findUtente(principal.getName());
                prenotaDao.saveUtenti(u, v);
            } catch (Exception e) {
                
                
                return "errorePrenotazione";
                // TODO Auto-generated catch block
            }
            
            
             return "prenotazione";
        
            }
    
    
        
        
    }



    quindi se tutto va bene mi ritorna prenotazione...
    questa è la mia pagina prenotazione.jsp:

    Codice:
    
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
       pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>il volo è stato correttamente prenotato</title>
    </head>
    <body>
    il volo è stato correttamente prenotato
    
    
    <br/>
    <br/>
    <br/>
    
    
    <a href="voli" >LISTA DEI VOLI DISPONIBILI  </a><br></br>
    
    
    <a href="logout" >LOGOUT  </a><br></br>
    </body>
    </html>


    il problema è che quando clicco sul link LISTA DEI VOLI DISPONIBILI al posto di andare nell'url /voli va su /prenota/voli....
    eppure su href ho scritto che deve andare su /voli.....
    come è possibile?
    in tutte le altre pagine gli stessi link funzionano perfettamente

  14. #14
    Il Puppies L'avatar di MscG
    Data Registrazione
    15-09-01
    Località
    Monti abruzzesi
    Messaggi
    777

    Predefinito Re: Spring Security+hibernate

    Codice:
    <a href="voli" >LISTA DEI VOLI DISPONIBILI  </a>
    Qui definisci una URL relativa. Se la pagina che ospita il link si trova a http://iltuoserver/latuaapp/prenota/qualcosa il link risultante sarà http://iltuoserver/latuaapp/prenota/voli. Sostituisci con:

    Codice:
    <a href="<c:url value="voli" />" >LISTA DEI VOLI DISPONIBILI  </a>
    Ed otterrai la url assoluta che ti serve!

Permessi di Scrittura

  • Tu non puoi inviare nuove discussioni
  • Tu non puoi inviare risposte
  • Tu non puoi inviare allegati
  • Tu non puoi modificare i tuoi messaggi
  • Il codice BB è Attivato
  • Le faccine sono Attivato
  • Il codice [IMG] è Attivato
  • Il codice HTML è Disattivato