Using Google API with spring-security-oauth2.0 - spring-security

I've searched here a bit but could not find an answer to my issue.
I implement oAuth client with spring-sec-oAuth 2.0 (1.0.0.RC2a). After properly setting the beans.xml, I happily get a valid token and all looks good. Then, I want to use Calendar APIs - I'm not sure how do I make the call to get the Calendar object.
My (relevant) settings: (spring-servlet.xml)
<!--apply the oauth client context-->
<oauth:client id="oauth2ClientFilter" />
<oauth:resource id="google"
type="authorization_code"
client-id="<my client id>"
client-secret="<my client secret>"
access-token-uri="https://accounts.google.com/o/oauth2/token"
user-authorization-uri="https://accounts.google.com/o/oauth2/auth"
scope="https://www.googleapis.com/auth/calendar"
client-authentication-scheme="form"
pre-established-redirect-uri="https://ohad.sealdoc.com/oauth2-client/hello" />
<bean id="googleClientService" class="com...GoogleClientServiceImpl">
<property name="butkeDemoRestTemplate">
<oauth:rest-template resource="google" />
</property>
and the implementation class:
public class GoogleClientServiceImpl implements DemoService
{
private RestOperations butkeDemoRestTemplate;
#Override
public String getTrustedMessage()
{
String dataUri = "https://www.googleapis.com/calendar/v3/users/me/calendarList?minAccessRole=writer";
Calendar service = butkeDemoRestTemplate.getForObject(dataUri, Calendar.class);
return "demo";
}
}
Doing so ends up with:
Request processing failed; nested exception is
error="invalid_request",
error_description="{errors=[{domain=usageLimits,
reason=accessNotConfigured, message=Access Not Configured}], code=403,
message=Access Not Configured}"
Definitely, I'm doing something wrong in my "getTrustedMessage()", so I'm hear to consult the experts... I DO want to use OAuth2RestTemplate, but how do I know the URI I should use? After searching (Google), I found only examples of Google code, and they use Google oAuth (which I do not want to use - I'd rather use Spring implementation for my client)
any ideas?

GOT IT!
I've resolved this problem (getting the "403, message=Access Not Configured" thing) by simply enabling the specific service in Google APIs Console, under "Services"...

Related

Spring Security : How to Authorize functions without log in

I implemented spring security in my web application. Now all my services are secured and can be only invoked by authorised users. Everything works on webside, but when I call function without log in doesn't work.
here is my Controller(RestController)
#RestController
public class MessageService {
#Autowired
MessageModel messageModel;
#RequestMapping(value="/message",method=RequestMethod.POST)
public Message save(#RequestBody Message message) {
return messageModel.save(message);
}
#PreAuthorize("permitAll()")
#RequestMapping(value="/messagee",method=RequestMethod.POST)
public Message savee(#RequestBody Message message) {
System.out.println("hjgjhghggfhgf");
return messageModel.savee(message);
}
}
I am using angularjs client side.
The functions are not supposed to work as they are secured by spring security. To allow a few functions to be accessed anonymously, you need to configure spring security to do so.
Depending on what configuration you are using, I would suggest the below:
If you are using XML/Java route based config, I would recommend you to do something like this:
<security:intercept-url pattern="/trusted/**" filters="none" />
<security:intercept-url pattern="/**" access="isFullyAuthenticated()" />
If you are using the #PreAuthorize annotation, I would recommend you to do something like this:
#PreAuthorize("permitAll()")
public void YourAnonymousController(){
}
Hope this is what you are looking for.
EDIT 1: Please note that you remove the route based security config. Try adding #PreAuthorize("hasRole()") on functions you want to keep secured and #PreAuthorize("permitAll()") on anonymous functions.

How to secure Spring Security's ActiveDirectoryLdapAuthenticationProvider network interactions

From my own inspection of the source and everything I have so far read, Spring Security's ActiveDirectoryLdapAuthenticationProvider (http://docs.spring.io/spring-security/site/docs/3.2.8.RELEASE/reference/htmlsingle/#ldap-active-directory) interacts with ActiveDirectory "in the clear"...passwords are transmitted using plain text.
I have see questions such as How does Spring Security LDAP protect password during Active Directory authentication?, but this only confirms my concern. My google-fu has not been good enough for me to have found a clear solution as yet.
I am working with a utility that is tightening up security significantly and I don't believe that my current use of ActiveDirectoryLdapAuthenticationProvider (with plaintext passwords) will be acceptable for much longer.
I currently use AD to authenticate a user and to validate that the presented user has been granted a role that lets them use the application making the request.
(I am not above ripping Spring Security out if I have to, but I strongly suspect that my managers' fear factor would increase quite significantly if I brought this to them, so I am looking for a minimal change, if such is at all possible...)
I believe the AD instance is Windows Server 2008 R2.
I am using ldap://...:389. My attempt to use ldaps://...:636 fails (but i don't currently have the exact message to hand; it's the weekend...apologies).
I can't believe that I am the only person out there with this need, so is there anyone out there with experience that can point me towards the 'canonical' solution?
Had used spring-ldap module to achieve your requirement.
What I did was :
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="contextSource" />
</bean>
<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="--ldaps url goes here" />
<property name="userDn"
value="--user dn goes here" />
<property name="password"
value="--password goes here" />
</bean>
In one of the service classes autowired ldapTemplate.
Had a method which looked something like this:
public boolean authenticate(final String username, final String password)
throws MyException {
//searchAttribute is bean attribute here
final String searchQuery = "(" + searchAttribute + "=" + username + ")";
boolean status = false;
AuthenticationErrorCallback callback = new SpringLdapAuthenticationErrorCallback();
try {
status = ldapTemplate.authenticate(basePath, searchQuery, password,
callback);
if (!status) {
LOGGER.error("Error while ldap authencation" + callback);
throw new MyException(
ErrorEnum.INVALID_USER.getCode(),
ErrorEnum.INVALID_USER.getDescription());
}
} catch (Exception ex) {
LOGGER.error("Error while ldap authencation" + ex);
throw new MyException(ErrorEnum.INVALID_USER.getCode(),
ErrorEnum.INVALID_USER.getDescription());
}
return status;
When using ldaps you should take care to add ldap servers certificate to your truststore. Since most of the time it would be a self signed certificate.
Also check if server support anonymous authentication.
If it does not then you will need a user which will first bind to ldap
and then authenticate the incoming request.
Hope this helps.

Does AOP with AspectJ works with method from Managed Bean called from the view in JSF2?

I’m currently facing a Problem using a combination of JSF 2 and AOP with AspectJ annotation.
I don't know if Spring AOP is playing a role here...(I didn't well understand difference between SPRING AOP, ASPECTJ, GOOGLE GUICE...that's an another question)
I'm trying to send an e-mail after i added some values in my database via click on a form in jsf view.
I have a managedBean AddPartipant handled by JSF (linked to a view) to add participant via a form. I want to intercept the method who makes the change in database and send an email just after this action.
I have a spring bean SendMailBoImpl with a method to send an email.(sending works ok)
I found using a AOP was a good way. It's works only when i trying to make it works in a main...not in the complete webapp. I read some stuffs about problem context spring / Jsf but don't found a solution...yet...
I know my method to add data in the database via the view is ok...but the mail is never sent whereas the database is modified.
Somebody has an idea ?
Thanks a lot :)
AddParticipant ManagedBean :
public class AddParticipant implements Serializable{
//DI via Spring
ParticipantBo participantBo;
private String id_study ;
private Participant aParticipant = new Participant();
//getters and setters
public void addParticipant(){
aParticipant.setId_study (id_study);
...
participantBo.save(aParticipant);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Ajout du participant "+id_study+" dans l'étude "+ study_name));
}
MaiBo Service :
#After("execution(* com.clb.genomic.lyon.beans.AddParticipant.addParticipant(..))")
public void sendMail() {
....
mailSender.send(message);
....
}
My bean config :
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="addParticipant" class="com.clb.genomic.lyon.beans.AddParticipant"/>
<bean id="sendMailBo" class="com.clb.genomic.lyon.bo.SendMailBoImpl">
<property name="mailSender" ref="mailSender" />
<property name="simpleMailMessage" ref="customeMailMessage" />
</bean>
When i do this it's working :
ApplicationContext appContext = new ClassPathXmlApplicationContext
( "classpath:webConfiguration/applicationContext.xml");
AddParticipant aspect = (AddParticipant) appContext.getBean("addParticipant");
aspect.addParticipant();
Solved base on the read of this : http://kumarnvm.blogspot.fr/2012/07/using-spring-to-manage-jsf-september-10_14.html

JSF 2 and the Basic HTTP authentication

We have an web app what uses Basic HTTP authentication.
web.xml
...
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>file</realm-name>
</login-config>
...
Indirect usage somewhere in the deep code space ...
User getLogedUser(HttpServletRequest request)
And I have to rewrite it in JSF 2, but I have no clue how can use the this authentication method in JSF 2. (i could not find the way how can i get 'HttpServletRequest request')
Google did not throw any useful hit on his first page
Thanks for the answers in advance.
The raw HttpServletRequest is in JSF available by ExternalContext#getRequest().
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
HttpServletRequest request = (HttpServletRequest) ec.getRequest();
// ...
However, I think it's better to change the getLoggedUser() method to take the remote user instead.
User getLoggedUser(String remoteUser)
so that you can just feed either ExternalContext#getRemoteUser() or HttpServletRequest#getRemoteUser() to it. This also decouples the method from any Servlet API or JSF API dependency.
I guess you are looking for ExternalContext.getRemoteUser()
which returns the user name.
Usage:
FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();

Spring Security Authentication using MyBatis

I am trying to perform Spring Security Authentication using MyBatis.
My spring-security file looks as follows
<global-method-security pre-post-annotations="enabled" />
<beans:bean id="myUserService"
class="com.service.CustomService" />
<authentication-manager>
<authentication-provider user-service-ref="myUserService" />
</authentication-manager>
My CustomService class implements UserDetailsService and in the loadUserByUsername method , I am using my MyBatis Dao to load the Users from the DB.
#Autowired
private MyBatisDao dao;
In my Controller class I am using the same annotation , and in that case it returns the proper object.
But when I use the same in the CustomService class it returns null.
I am unable to understand the reason for it. Am i missing something. Please help
Any example of Spring Authentication using MyBatis would help, I can understand it and then maybe figure out the issue
I fix this issue by another - not recommended way.
In this case, #controller can treat the db work right,
so I do basic auth in controller and send that result to custom service.
Custom service has no valid auth function in this case.
If useename and password is valid, custom service is called,
and that just returns dummy auth result.
If username and password is invalid, i just didn't call the auth in controller.
Though it's not quite right way, it works fine with some special treat for user role.
I want to know there's a better way to solve this problem,
but i have no time to find, right now.
Issue solved by taking an alternative approach in constructing the MyBatis Object.
I created a singleton class which returns the SqlSessionFactory Object, and using the same in my code for calling the Mapper Interfaces methods.
Sample code snippet below
InputStream myBatisConfigStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("config.xml");
if (null == sqlSessionFactory){
sqlSessionFactory = new SqlSessionFactoryBuilder().build(myBatisConfigStream);
sqlSessionFactory.getConfiguration().addMapper(IOMapper.class);
}
try {
myBatisConfigStream.close();
} catch (IOException e) {
e.printStackTrace();
}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
The config.xml file contains only the dataSource.
Hope this helps.

Resources