Thursday, November 25, 2010

Re: RequestFactory Security/Authentication

actually i'm only getting xml output; looks kinda strange.


how does your header look like?

---

xmlns:jsp="http://java.sun.com/JSP/Page"><jsp:output
omit-xml-declaration="yes" /> 


---
thx
On 24.11.2010, at 17:13, Ramon Buckland wrote:

Hi Patrick,

I just finished (10 mins ago) implementing my Spring Security service
over the top of the Requestfactory.

I am sure there are some holes (not security ones, just stuff I have
missed) but here is what I did.
I have a user entity (that represents the user). this entity has the
username, and the password.

@Entity
@Configurable
public class IsuproUser {

   private String username;

   private String password;

   @OneToOne
   private Person person;

   // clear or sha256
   private String passwordEncoding;

   private boolean enabled;
}

/* and example table insert for a user then looks like
INSERT INTO isupro_user (password, username,person, enabled,
password_encoding) VALUES
('5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8','rbuckland',
1, 1, 'sha256')
sha256 value is 'password'.

echo -n password | sha256sum

*/


I have a fairly clean META-INF/spring/applicationContext-security.xml
file.

<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/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 security configurations -->
 <http auto-config="true" use-expressions="true">
   <form-login login-processing-url="/resources/
j_spring_security_check"
               login-page="/login.jspx"
               authentication-failure-url="/login.jspx?
login_error=t" />
   <logout logout-url="/resources/j_spring_security_logout" />

   <!-- Configure these elements to secure URIs in your application --

   <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" /

   <intercept-url pattern="/gwtRequest/**"
access="isAuthenticated()" />
   <intercept-url pattern="/isupro.jsp" access="isAuthenticated()" />
   <intercept-url pattern="/**" access="permitAll" />

 </http>

 <beans:bean
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"
id="passwordEncoder">
   <beans:constructor-arg value="256" />
 </beans:bean>

 <beans:bean id="myUserDetailsService"
class="isupro.security.IsuproUserDetailsService" />

<!-- Configure Authentication mechanism -->
 <authentication-manager alias="authenticationManager">
   <authentication-provider user-service-ref="myUserDetailsService">
     <password-encoder ref="passwordEncoder" />
   </authentication-provider>
 </authentication-manager>

</beans:beans>


So I have (hopefully) secured the app, on the isupro.jsp (this is the
GWT bootstrap).

I have a UserDetails class. Which is just a minor extension on the
spring one (seems there is some depecation for this "User" class.. but
I moved on :-) worry about that later ).

public class IsuproUserDetails extends User {

   private IsuproUser isuproUser;

   private static final long serialVersionUID = 1L;

   @SuppressWarnings("deprecation")
   public IsuproUserDetails(IsuproUser isuproUser) {
       super(isuproUser.getUsername(), isuproUser.getPassword(),
isuproUser.getEnabled(),true, true, true, getAuthorities(false));
       this.setIsuproUser(isuproUser);
   }

   // threading issue here .. change
   private static GrantedAuthority[] getAuthorities(boolean isAdmin)
{
       List<GrantedAuthority> authList = new
ArrayList<GrantedAuthority>(2);
       authList.add(new GrantedAuthorityImpl("ROLE_USER"));
       if (isAdmin) {
           authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
       }
       return authList.toArray(new GrantedAuthority[] {});
   }

   public void setIsuproUser(IsuproUser isuproUser) {
       this.isuproUser = isuproUser;
   }

   public IsuproUser getIsuproUser() {
       return isuproUser;
   }

}

Now we have two more classes to care about. first, the one that
SpringSecurity needs, the UserDetails service. I use JPA (it was an
app based off ROO (side note: I find ROO cumbersome! :-/ )


public class IsuproUserDetailsService implements UserDetailsService {

   @Override
   public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException, DataAccessException {
       IsuproUser isuproUser =
IsuproUser.findUserByUsername(username);
       if (isuproUser != null) {
           return new IsuproUserDetails(isuproUser);
       } else {
           throw new UsernameNotFoundException("Username : " +
username + " : was not found");
       }
   }

}

And then the one that the GWT RequestFactory needs.

public class IsuproUserInformation extends UserInformation {

   public IsuproUserInformation(String redirectUrl) {
       super(redirectUrl);
   }

   @Override
   public String getEmail() {
       return "email@address.com";
   }

   @Override
   public Long getId() {
       if
(SecurityContextHolder.getContext().getAuthentication().isAuthenticated())
{
           IsuproUserDetails userdetails = (IsuproUserDetails)
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
           return userdetails.getIsuproUser().getId();
       } else {
           return -1L;
       }
   }

   @Override
   public String getLoginUrl() {
       return "/login.jspx";
   }

   @Override
   public String getLogoutUrl() {

       return "/logout";
   }

   @Override
   public String getName() {
       if
(SecurityContextHolder.getContext().getAuthentication().isAuthenticated())
{
           IsuproUserDetails userdetails = (IsuproUserDetails)
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
           return userdetails.getIsuproUser().getUsername(); // this
could be the name of the getPerson()
       } else {
           return "Guest";
       }

   }

   @Override
   public boolean isUserLoggedIn() {
       return
SecurityContextHolder.getContext().getAuthentication().isAuthenticated();
   }

   @Override
   public void setId(Long id) {
       // we don't allow setting the ID
   }

}


And finally, telling the GWT Requestfactory about this UserInformation
class.

 <servlet>
   <servlet-name>requestFactory</servlet-name>
   <servlet-
class>com.google.gwt.requestfactory.server.RequestFactoryServlet</
servlet-class>
   <init-param>
     <param-name>userInfoClass</param-name>
     <param-value>isupro.security.IsuproUserInformation</param-value>
   </init-param>
 </servlet>

So now, If i navigate to /isupro.jsp, it pushes me to /login.jspx. I
login with the username/password(database has an encrypted sha256
value of the password and spring does the magic of sha-ing the
password for comparison.

A nice tutorial (for others to read is here).
http://www.packtpub.com/article/spring-security-configuring-secure-passwords


This is what it looks like in GWT to pull that user up. (Straight from
Spring ROO).

       /*
        * identify the logged in user
        */
       Receiver<UserInformationProxy> receiver = new
Receiver<UserInformationProxy>() {
           public void onSuccess(UserInformationProxy
userInformationProxy) {

shell.getLoginWidget().setUserInformation(userInformationProxy);
           }
       };

requestFactory.userInformationRequest().getCurrentUserInformation(Window.Location.getHref()).fire(receiver);


That is it.

HTH
Ramon Buckland

On Nov 12, 1:32 pm, Patrick Hilsbos <patrick.hils...@cloudsters.net>
wrote:
Hi,
could you get a bit more in detail, how to implement the auth - e.g. where to store the authcode?
Do i have to create a session on my own...?

I already went through a couple of projects dealing with spring security / acegi.

Thanks !!!

On 10.11.2010, at 17:57, Jack wrote:

Everytime a request is made the RequestFactoryServlet loads an
implementation of UserInformation and calls boolean isUserLoggedIn().
If you do not provide a custom UserInformation implementation a
SimpleUserInformationImpl will be choosen which always returns true
for isUserLoggedIn().

To define a custom UserInformation implementation you need to add to
your web.xml something like this:

<servlet>
 <servlet-name>requestFactoryServlet</servlet-name>
 <servlet-
class>com.google.gwt.requestfactory.server.RequestFactoryServlet</
servlet-class>
 <init-param>
    <param-name>userInfoClass</param-name>
    <param-value>your.example.YourUserInformationImpl</param-value>
 </init-param>
</servlet>

With your own UserInformation implementation you can check if an user
is logged in. Inside the isUserLoggedIn() method you can access the
HttpServletRequest object via

HttpServletRequest request =
RequestFactoryServlet.getThreadLocalRequest();

Now you should have anything you need to authenticate the request
(request cookies, request headers, request session).

To do the actual login and logout of an user I would use a normal GWT
RemoteService with two methods

String login(String user, String password)
void logout(String authtoken)

On 9 Nov., 20:16, "Max E." <eckel....@gmail.com> wrote:
Hello,

I'm having problems to understand how User Authentication works with
the RequestFactory.
I do understand the documentation and the expenses example.

How is it possible to implement Authentication/ How do users login?
How can Users only view the Entities they are allowed to see.
How can the Server verify that they can only change/persist entities
they are allowed to change?

I did not find any tutorial or documentation about this. The only
thing I found was UserInformation and RequestSecurityProvider in GWT.

Can somebody explain this?

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
For more options, visit this group athttp://groups.google.com/group/google-web-toolkit?hl=en.



--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.


No comments:

Post a Comment