PDA

View Full Version : Why Authenticated is false


Zhukov2004
Sep 22nd, 2004, 01:29 AM
Help, please!

applicationContext:
<!-- =================== SECURITY SYSTEM DEFINITIONS ================== -->
<!-- RunAsManager -->
<bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl">
<property name="key"><value>my_run_as_password</value></property>
</bean>

<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHENTICATION DEFINITIONS ~~~~~~~~~~~~~~~~~~ -->

<bean id="runAsAuthenticationProvider" class="net.sf.acegisecurity.runas.RunAsImplAuthentication Provider">
<property name="key"><value>my_run_as_password</value></property>
</bean>

<!-- ~~~~~~~~~~~~~~~~~~~~ AUTHENTICATION DEFINITIONS ~~~~~~~~~~~~~~~~~~ -->

<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="runAsAuthenticationProvider"/>
<ref bean="daoAuthenticationProvider"/>
</list>
</property>
</bean>


<!-- =================== SECURITY BEANS YOU SHOULD CHANGE ================== -->

<!-- If you replace this bean with say JdbcDaoImpl, just ensure your replacement
has the same bean id (authenticationDao) -->
<bean id="authenticationDao" class="ru.zhukov.document.model.dao.hibernate.Authenticat ionHibernateDao">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate"/>
</property>
</bean>
<bean id="passwordEncoder" class="net.sf.acegisecurity.providers.encoding.Md5Passwor dEncoder"/>

<bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticati onProvider">
<property name="authenticationDao"><ref bean="authenticationDao"/></property>
<property name="userCache"><ref bean="userCache"/></property>
<property name="passwordEncoder"><ref bean="passwordEncoder"/></property>

</bean>
<bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBa sedUserCache">
<property name="minutesToIdle"><value>5</value></property>
</bean>

<bean id="loggerListener" class="net.sf.acegisecurity.providers.dao.event.LoggerLis tener"/>

<bean id="autoIntegrationFilter" class="net.sf.acegisecurity.ui.AutoIntegrationFilter" />

<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>

<!-- ================================================== =================================== -->




<!-- =================== SECURITY BEANS YOU WILL RARELY (IF EVER) CHANGE ================== -->


<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>

<bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProce ssingFilter">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="authenticationFailureUrl"><value>/login.jsf?login_error=1</value></property>
<property name="defaultTargetUrl"><value>/</value></property>
<property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>
</bean>

<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforce mentFilter">
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
<property name="authenticationEntryPoint"><ref bean="authenticationProcessingFilterEntryPoint"/></property>
</bean>

<bean id="authenticationProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProce ssingFilterEntryPoint">
<property name="loginFormUrl"><value>/login.jsf</value></property>
<property name="forceHttps"><value>false</value></property>
</bean>

<!-- Note the order that entries are placed against the objectDefinitionSource is critical.
The FilterSecurityInterceptor will work from the top of the list down to the FIRST pattern that matches the request URL.
Accordingly, you should place MOST SPECIFIC (ie a/b/c/d.*) expressions first, with LEAST SPECIFIC (ie a/.*) expressions last -->
<bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityI nterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/view/**=ROLE_TELLER,ROLE_SUPERVISOR
/admin/**=ROLE_SUPERVISOR

</value>
</property>
</bean>



I've my session :

{/login.jsp=javax.faces.component.UIViewRoot@39d325, com.sun.faces.VIEW_LIST=[/login.jsp], ACEGI_SECURITY_AUTHENTICATION=net.sf.acegisecurity .providers.UsernamePasswordAuthenticationToken@1f9 f0f2: Username: Zhukov; Password: [PROTECTED]; Authenticated: false; Details: null; Granted Authorities: ROLE_SUPERVISOR, userLoginBean=ru.zhukov.document.view.bean.user.Us erLoginBean@1da2737, javax.faces.request.charset=ISO-8859-5}{}



Why :Authenticated is false

Ben Alex
Sep 23rd, 2004, 07:09 PM
The Authentication.authenticated property is only set to true by AbstractSecurityInterceptor:


// Attempt authentication
Authentication authenticated = this.authenticationManager
.authenticate(context.getAuthentication());
authenticated.setAuthenticated(true);
logger.debug("Authenticated: " + authenticated.toString());
context.setAuthentication(authenticated);
ContextHolder.setContext((Context) context);

gab
Jun 12th, 2007, 05:20 AM
Hi Ben
I extended JdbcDaoImpl because I need to connect a non-acegi-standard database. The problem is I'am getting 'Authenticated: false' even if the username/password/role are correct...

---------------------------------------- ERROR
[DEBUG,XmlWebApplicationContext,http-8080-Processor24] Publishing event in context [Root WebApplicationContext]: org.acegisecurity.event.authentication.Authenticat ionFailureBadCredentialsEvent[source=org.acegisecurity.providers.UsernamePasswor dAuthenticationToken@eb4f29c4: Username: reelem; Password: [PROTECTED]; Authenticated: false; Details: org.acegisecurity.ui.WebAuthenticationDetails@4345 8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 2FAC85FE514737261EB2E884174D1870; Not granted any authorities]

---------------------------------------- CODE
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import javax.sql.DataSource;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.userdetails.User;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UsernameNotFoundExce ption;
import org.acegisecurity.userdetails.jdbc.JdbcDaoImpl;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class AuthenticationJdbcDaoImpl extends JdbcDaoImpl {

protected Log logger = LogFactory.getLog(getClass());

//private long personId;
public AuthenticationJdbcDaoImpl() {
super();
}

protected void initMappingSqlQueries() {
super.setUsersByUsernameQuery("SELECT webuserid as username, webpasswd as password, case when isawbaktiv = 'T' then 'true' else 'false' end as enabled, personid FROM ... WHERE webuserid = ?");
super.setAuthoritiesByUsernameQuery("SELECT aut.authority FROM ... aut INNER JOIN ... on aut.personid = ben.personid WHERE ben.webuserid = ?");
super.initMappingSqlQueries();
this.usersByUsernameMapping = new CustomUsersByUsernameMapping(this.getDataSource()) ;
this.authoritiesByUsernameMapping = new CustomAuthoritiesByUsernameMapping(this.getDataSou rce());
logger.info("********** AUTHENTICATION: query users = " + getUsersByUsernameQuery());
logger.info("********** AUTHENTICATION: query authorities = " + getAuthoritiesByUsernameQuery());
}

public UserDetails loadUserByUsername(String username) {
try {
// is instance of User and is not a CustomUser, as I would expect…
UserDetails u = super.loadUserByUsername(username);
String str = "********** AUTHENTICATION: ...load userName = "+ u.getUsername();
GrantedAuthority[] roles = u.getAuthorities();
for (int i = 0; i < roles.length; i++) {
str += "\n - " + roles[i].getAuthority();
}
logger.info("********** AUTHENTICATION: "+str);
return u;
} catch (UsernameNotFoundException e1) {
logger.info("********** AUTHENTICATION: "+e1.getMessage());
throw e1;
} catch (DataAccessException e2) {
logger.info("********** AUTHENTICATION: "+e2.getMessage());
throw e2;
}
}

protected class CustomUsersByUsernameMapping extends MappingSqlQuery {

protected CustomUsersByUsernameMapping(DataSource ds) {
super(ds, getUsersByUsernameQuery());
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}

protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
String username = rs.getString(1);
String password = rs.getString(2);
String enabled_str = rs.getString(3);
boolean enabled = false;
if ("true".equalsIgnoreCase(enabled_str)) {
enabled = true;
}
// get custom user attributes
//personId = rs.getLong(4);

User user = new User(username, password, enabled, true, true, true,
new GrantedAuthority[0]);
logger.info("********** AUTHENTICATION: ...mapRow user = " + user.getUsername());
return user;
}
}

protected class CustomAuthoritiesByUsernameMapping extends MappingSqlQuery {
protected CustomAuthoritiesByUsernameMapping(DataSource ds) {
super(ds, getAuthoritiesByUsernameQuery());
declareParameter(new SqlParameter(12));
compile();
}

protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
String roleName = "ROLE_" + rs.getString(1);
GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);
logger.info("********** AUTHENTICATION: ...mapRow authority = " + roleName);
return authority;
}
}

public void setLogger(Log logger) {
this.logger = logger;
}
}


thnx for urgent help,
gab

gab
Jun 12th, 2007, 09:02 AM
Hi Ben
I just found the bug...
the code was correct, just the password had to be trimmed when selecting from the database.
gab

:rolleyes:

gregturn
Jun 12th, 2007, 11:27 AM
JdbcDaoImpl let's you set the queries without extending the whole class. You can set bean properties usersByUsernameMapping and authoritiesByUsernameMapping to plug in your own customized query.

karldmoore
Jun 12th, 2007, 03:06 PM
Indeed this example seems to be able to just inject the SQL, one thing you'd also need to do is setRolePrefix("ROLE_");
http://www.acegisecurity.org/multiproject/acegi-security/apidocs/org/acegisecurity/userdetails/jdbc/JdbcDaoImpl.html#setRolePrefix(java.lang.String)

gregturn
Jun 12th, 2007, 04:49 PM
Indeed this example seems to be able to just inject the SQL, one thing you'd also need to do is setRolePrefix("ROLE_");
http://www.acegisecurity.org/multiproject/acegi-security/apidocs/org/acegisecurity/userdetails/jdbc/JdbcDaoImpl.html#setRolePrefix(java.lang.String)

Only if you want to change that prefix, or totally remove it, would you need to adjust that bean property.

karldmoore
Jun 12th, 2007, 04:56 PM
Only if you want to change that prefix, or totally remove it, would you need to adjust that bean property.

I was just commenting on the user's example code, it appears to adding the ROLE_ prefix to the front of the retrieved names. The default role prefix is empty.
http://63.246.29.165/multiproject/acegi-security/xref/org/acegisecurity/userdetails/jdbc/JdbcDaoImpl.html

gab
Jun 13th, 2007, 05:21 AM
Hi
First many thnx for your quick information. the reason why I made a specific JdbcDaoImpl extension was because I add the authentication with specific user data (id's, name, adress etc.). I just waited with that until the authentication worked.
salutti,
gab

karldmoore
Jun 13th, 2007, 08:06 AM
If that's the way you are going, one thing to be aware of is the default behaviour of JdbcDaoImpl always returning true for accountNonExpired, credentialsNonExpired and accountNonLocked. This caught me out before. I ended up just creating my own Dao instead.

trdyer
Oct 24th, 2007, 12:46 PM
does jdbcDaoImpl trim the password length from the database automatically?