Page 1 of 2 12 LastLast
Results 1 to 10 of 20

Thread: Custom authorization - 0.8.2 to 0.9 upgrade woes

  1. #1

    Unhappy Custom authorization - 0.8.2 to 0.9 upgrade woes

    Hi

    We have a Spring application that uses customised authorization to integrate with our corporate user database using acegi 0.8.2.

    Here's the changed config:

    <bean id="regAuthenticationDAO" class="uk.co.anm.london.security.RegJdbcDaoImpl">
    <property name="dataSource">
    <ref bean="regSource"/>
    </property>
    <property name="usersByUsernameMapping">
    <ref bean="usersByUsernameMapping"/>
    </property>
    <property name="authoritiesByUsernameMapping">
    <ref bean="authoritiesByUsernameMapping"/>
    </property>
    </bean>

    <!-- New bean(s) to override Acegi queries -->
    <bean id="usersByUsernameMapping" class="uk.co.anm.london.security.mapping.UserByUse rnameMapping">
    <property name="dataSource">
    <ref bean="regSource" />
    </property>
    <property name="sql">
    <value>SELECT userid, email as username,password,'true' as enabled FROM users WHERE email = ? and valid='Y'</value>
    </property>
    </bean>

    <bean id="authoritiesByUsernameMapping" class="uk.co.anm.london.security.mapping.Authoriti esByUsernameMapping">
    <property name="dataSource">
    <ref bean="regSource" />
    </property>
    <property name="sql">
    <value>SELECT email as username, 'REGISTERED_USER' as authority FROM users WHERE email = ? and valid='Y'</value>
    </property>
    </bean>



    <bean id="registrationAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthe nticationProvider">
    <property name="authenticationDao"><ref local="regAuthenticationDAO"/></property>
    <property name="userCache"><ref local="acegiUserCache"/></property>
    </bean>

    <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderMana ger">
    <property name="providers">
    <list>
    <ref local="registrationAuthenticationProvider"/>
    <ref local="rememberMeAuthenticationProvider"/>
    </list>
    </property>
    </bean>

    This has been working fine but what we now need to do is to chain another authentication provider. I've read that 0.8.* doesn't do this very elegantly but 0.9 does. So off I go and download the 0.9 jar and find that the getters and setters for both usersByUsernameMapping and authoritiesByUsernameMapping have been refactored out and that the MappingSqlQuery inner classes are now private.

    I have 2 questions:

    1. How do I now customize the queries?

    2. Why!?!? This really irritating as I've already had to change all this once before when upgrading to 0.8 in the first place. I've also seen that all the packages have changed in 1.0. Should we go straight to that and avoid yet more refactoring hassle.

    Many thanks

    Charlie

  2. #2
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Go for the latest version, think its 1.0.3! If all you want to do is use custom queries, you can just inject these into the JdbcDaoImpl you don't need a subclass.

  3. #3

    Default

    Blimey that was quick - Thanks but there is something I forgot to add.

    I subclassed UserByUsernameMapping so it could return a custom user object because we use an extra id to track and record user activity on the site. Here's the code FYI.


    package uk.co.anm.london.security;

    import net.sf.acegisecurity.GrantedAuthority;
    import net.sf.acegisecurity.GrantedAuthorityImpl;

    @SuppressWarnings("serial")
    public class RegUser extends net.sf.acegisecurity.providers.dao.User{

    private Long id;

    public RegUser() {
    super();
    }

    public RegUser(Long userId, String userName, String password) throws IllegalArgumentException {
    super(userName, password, true, true, true, true, new GrantedAuthority[]{new GrantedAuthorityImpl("HOLDER")});
    this.id = userId;
    }

    public RegUser(Long userId, String userName, String password, GrantedAuthority[] authorities ) throws IllegalArgumentException {
    super(userName, password, true, true, true, true, authorities);
    this.id = userId;
    }

    public Long getId() {
    return id;
    }

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


    }


    package uk.co.anm.london.security.mapping;

    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Types;

    import javax.sql.DataSource;

    import org.springframework.jdbc.core.SqlParameter;
    import org.springframework.jdbc.object.MappingSqlQuery;

    import uk.co.anm.london.security.RegUser;

    public class UserByUsernameMapping extends MappingSqlQuery {

    public UserByUsernameMapping() {
    super();
    // TODO Auto-generated constructor stub
    }

    public UserByUsernameMapping(DataSource arg0, String arg1) {
    super(arg0, arg1);
    // TODO Auto-generated constructor stub
    }

    @Override
    public void setSql(String sql) {
    super.setSql(sql);
    declareParameter(new SqlParameter(Types.VARCHAR));
    compile();
    }

    @Override
    protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {
    Long id = rs.getLong(1);
    String username = rs.getString(2);
    String password = rs.getString(3);

    RegUser ret = new RegUser(id, username, password);
    return ret;
    }
    }

    So I need to get round this as well.
    If anyone can help it will make my day.

    cheers

    Charlie

  4. #4
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    In that case just carry on extending JdbcDaoImpl but override initMappingSqlQueries. You can then get it to use your mappings instead.

    This is was the JdbcDaoImpl does, just create your mappings instead.
    Code:
        protected void initMappingSqlQueries() {
            this.usersByUsernameMapping = new UsersByUsernameMapping(getDataSource());
            this.authoritiesByUsernameMapping = new AuthoritiesByUsernameMapping(getDataSource());
        }
    As for the net.sf to org.acegisecurity change, it's always a pain when this happens but such is life for these things. Early adoption and all that. Hibernate did the same thing from 2 to 3 (I think it was those versions anway).

  5. #5

    Default

    Brilliant - Thanks, Looks like a goer as the SQLMapping queries are now protected in 1.0.3 and not private as v 0.9.

    It is still a bit baffling that they were private with getters and setters in v 0.8, private without them and then protected in v1.*. I take your point about early adopters though - Them's the risks I guess. I'll post back if it works.

    Many many thanks

    Charlie

  6. #6

    Default

    After a brief but bloody struggle with the new configuration all is working perfectly.

    Thanks for your suggestions.

    If anyone wants the source code and configs just send me a private message.

    Hooray!

  7. #7
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Glad you got it all working! I do know what you mean with; you can inject them, the methods private, the methods protected. I would have thought injection really would make more sense, thats what Spring is all about!

  8. #8
    Join Date
    Feb 2007
    Posts
    8

    Default

    Quote Originally Posted by zebthecat View Post
    After a brief but bloody struggle with the new configuration all is working perfectly.

    Thanks for your suggestions.

    If anyone wants the source code and configs just send me a private message.

    Hooray!
    Hi,
    Could you please provide me with the source code and config files because I have given up to get it to work. I tried with the latest version( 1.0.3 ) but if your config is for 0.8.2 then I will degrade to that version.
    Many thanks in advance.

  9. #9
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    The main thing here is the package name changes. If you have some specific problems, I might be able to help.

  10. #10
    Join Date
    Feb 2007
    Posts
    8

    Default

    Quote Originally Posted by karldmoore View Post
    The main thing here is the package name changes. If you have some specific problems, I might be able to help.
    my config looks like this. Please suggest me what I am doing wrong

    <bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoI mpl">
    <property name="dataSource"><ref bean="dataSource"/></property>
    <property name="usersByUsernameMapping">
    <ref bean="customUsersByUsernameMapping"/>
    </property>
    </bean>

    <bean id="customUsersByUsernameMapping" class="no.ya.vertigo.dao.impl.springjdbc.UserByUse rnameMapping">
    <property name="dataSource">
    <ref bean="dataSource" />
    </property>
    <property name="sql">
    <value>SELECT LoginName, UserPassword, Email, FirstName, LastName FROM Users WHERE LoginName=?</value>
    </property>
    </bean>

    and UserByUsernameMapping.java is as follows:

    package no.ya.vertigo.dao.impl.springjdbc;

    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Types;

    import javax.sql.DataSource;

    import no.ya.vertigo.domain.LoggedInMemberData;

    import org.springframework.jdbc.core.SqlParameter;
    import org.springframework.jdbc.object.MappingSqlQuery;

    public class UserByUsernameMapping extends MappingSqlQuery {

    private static org.apache.log4j.Logger log = org.apache.log4j.Logger
    .getLogger(UserByUsernameMapping.class);

    public UserByUsernameMapping() {
    super();
    log.debug("UserByUsernameMapping()");
    }

    public UserByUsernameMapping(DataSource dataSource, String sql) {
    super(dataSource, sql);
    log.debug("UserByUsernameMapping(DataSource dataSource, String sql)");
    }

    @Override
    public void setSql(String sql) {
    log.debug("entering setSql()");
    super.setSql(sql);
    declareParameter(new SqlParameter(Types.VARCHAR));
    compile();
    }

    @Override
    protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {
    log.debug("entering mapRow()");
    String loginName = rs.getString(1);
    String userPassword = rs.getString(2);
    String email = rs.getString(3);
    String firstName = rs.getString(4);
    String lastName = rs.getString(5);

    LoggedInMemberData ret = new LoggedInMemberData(loginName,
    userPassword, email, firstName, lastName);

    log.debug("LoggedInMemberData " + ret.toString());
    return ret;
    }
    }

    here is the stack trace
    org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'jdbcDaoImpl' defined in ServletContext resource [/WEB-INF/applicationContext-acegi-security.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyExcep tion: Invalid property 'usersByUsernameMapping' of bean class [org.acegisecurity.userdetails.jdbc.JdbcDaoImpl]: Bean property 'usersByUsernameMapping' is not writable or has an invalid setter method: Does the parameter type of the setter match the return type of the getter?
    org.springframework.beans.NotWritablePropertyExcep tion: Invalid property 'usersByUsernameMapping' of bean class [org.acegisecurity.userdetails.jdbc.JdbcDaoImpl]: Bean property 'usersByUsernameMapping' is not writable or has an invalid setter method: Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.BeanWrapperImpl.setPrope rtyValue(BeanWrapperImpl.java:831)
    at org.springframework.beans.BeanWrapperImpl.setPrope rtyValue(BeanWrapperImpl.java:733)

    at

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •