social to integrate my web application with Facebook, now when the user is logged-in in my web application using Facebook login, I am able to read data from his/her profile but whenever I am trying to perform some write operation like update status or publish a post on user's wall , I am getting an InsufficientPermissionException.
My Login form is:
<form name="fb_signin" id="fb_signin" action="${pageContext.request.contextPath}/auth/facebook">
<input type="hidden" name="scope" value="email,publish_stream,read_stream,user_status,user_photos,publish_actions,offline_access" />
<button class="btn btn-facebook" type="submit"> <i class="icon-facebook"></i>facebook</button>
</form>
The required part of config for this operation is:
<bean id="userIdSource" class="org.springframework.social.security.AuthenticationNameUserIdSource"/>
<bean id="facebookApiHelper" class="org.springframework.social.facebook.config.support.FacebookApiHelper">
<constructor-arg index="0" ref="usersConnectionRepository"/>
<constructor-arg index="1" ref="userIdSource"/>
</bean>
<bean id="connectionFactoryLocator" class="org.springframework.social.security.SocialAuthenticationServiceRegistry">
<property name="authenticationServices">
<list>
<bean class="org.springframework.social.facebook.security.FacebookAuthenticationService">
<constructor-arg value="${facebook.app.id}" />
<constructor-arg value="${facebook.app.secret}" />
<!-- Important: The next property name changed from "scope" to "defaultScope" in 1.1.0.M4 -->
<property name="defaultScope" value="email,publish_actions,publish_stream,read_stream,user_status,user_photos,offline_access" />
</bean>
</list>
</property>
</bean>
And now my controller is:
public class FacebookOperationController {
private static final Logger logger = LoggerFactory.getLogger(FacebookOperationController.class);
#Autowired
protected FacebookApiHelper facebookApiHelper;
#Autowired
UserIdSource userIdSource;
private UsersConnectionRepository usersConnectionRepository;
#Autowired
public FacebookOperationController(UsersConnectionRepository usersConnectionRepository)
{
this.usersConnectionRepository = usersConnectionRepository;
}
#RequestMapping(method = RequestMethod.GET)
public String shareWithFacebook(WebRequest request,Model model){
Facebook facebook = facebookApiHelper.getApi();
Connection<Facebook> connection = usersConnectionRepository.createConnectionRepository(userIdSource.getUserId()).findPrimaryConnection(Facebook.class);
//connection.updateStatus("hello world");
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.set("link", "www.equinoxrar.com");
map.set("name", "Hi This is a Test Post");
map.set("caption", "Link Caption");
map.set("description", "Loooooo....ng description here");
map.set("message", "hello world");
// THE BELOW LINES ARE THE CRITICAL PART I WAS LOOKING AT!
map.set("picture", "http://www.imageRepo.com/resources/test.png"); // the image on the left
//map.set("actions", "{'name':'myAction', 'link':'http://www.bla.com/action'}"); // custom actions as JSON string
//String a = facebook.publish(userIdSource.getUserId(), "feed", map);
String b = connection.getApi().publish(userIdSource.getUserId(), "feed", map);
//publish(userIdToPostTo, "feed", map);
return "tilesname";
}
}
I am able to perform read operation from this Controller but getting an InsufficientPermissionException for any write operation. Can anyone have any idea? The Exception I am getting here is:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.social.InsufficientPermissionException: Insufficient permission for this operation.
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
Actually I have solved the problem, I am able to post in facebook from my web app when I used the app admin login, but for test facebook apps only admin/developers/testers added to the facebook app can post, for all other we have to submit details (login review) of my app to facebook, once facebook approve the same, then it will be open for all usrs.
Could you please post more of the stacktrace to get some more into the error?
You could also try creating a org.springframework.social.facebook.api.FacebookLink object and posting using
facebook.feedOperations().postLink("i'm posting", link);
Related
I am designing a set of REST APIs for accessing the URLs. As per my requirement there are two URLs:
http://localhost:3126/securitydemo/webapi/db/students
to view all the students no access required and
http://localhost:3126/securitydemo/webapi/db/students/1
only ROLE_USER are allowed.
My Spring Security configuration:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="**/students/*" access="hasRole('ROLE_USER')" />
<http-basic/>
</http>
If I use the pattern **/students/* no basic security popup occurs. If I use /** it's working properly.
How can I intercept the two URLs with different security levels?
My REST service class:
#Path("/db")
#Produces(MediaType.APPLICATION_JSON)
public class StudentService {
static StudentDao data = new StudentDaoImpl();
#Path("/students")
#GET
public Response getStudents(){
GenericEntity<List<Student>> entity = new GenericEntity<List<Student>>(data.getAllStudents()){};
return Response.ok(entity).build();
}
#Path("/students/{id}")
#GET
public Response getStudent(#PathParam("id") int id){
return Response.ok(data.getStudent(id)).build();
}
}
try this
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/securitydemo/webapi/db/students/1/**" access="hasRole('ROLE_USER')" />
<http-basic/>
</http>
We have a custom authentication service which accepts a parameter over a REST service and provides a json response. Based on the response we redirect the user. I wish to integrate this webservice with our new Alfresco Box.
Is there a way to do custom base authentication instead of using LDAP or inbuilt SSO plugin?
If I understood correctly...
Implement your custom remote user mapper:
package best.package.ever;
import org.alfresco.repo.security.authentication.external.DefaultRemoteUserMapper;
public class CustomRemoteUserMapper extends DefaultRemoteUserMapper {
public boolean canHandle(HttpServletRequest request) {
return true; // TODO
}
public String getTrustedUserId(HttpServletRequest request) {
// TODO: validate & authorize... e.g. based on trusted Json Web Token
return "trusted.user.id"; // TODO
}
public String getRemoteUser(HttpServletRequest request) {
if (canHandle(request)) {
return getTrustedUserId(request);
} else {
return super.getRemoteUser(request);
}
}
}
Put your library best-package-ever.jar into tomcat\webapps\alfresco\WEB-INF\lib
Declare your custom bean and inject it into RemoteUserMapper bean: tomcat\shared\classes\alfresco\extension\authentication-custom-context.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="customRemoteUserMapper" class="best.package.ever.CustomRemoteUserMapper">
<property name="personService" ref="PersonService"/>
<property name="authorityService" ref="AuthorityService" />
</bean>
<bean id="RemoteUserMapper" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">
<property name="applicationContextManager">
<ref bean="Authentication" />
</property>
<property name="interfaces">
<list>
<value>org.alfresco.repo.security.authentication.external.RemoteUserMapper</value>
<value>org.alfresco.repo.management.subsystems.ActivateableBean</value>
</list>
</property>
<property name="sourceBeanName">
<value>customRemoteUserMapper</value> <!-- extending remoteUserMapper -->
</property>
</bean>
</beans>
I am trying to secure my REST services using spring security.My problem is ,I have stuck at authentication entry point.even though I have configured a UsernamePasswordAuthenticationFilter,execution flow could not reach there.
Below is the XML configuration
<sec:http create-session="stateless" auto-config="false"
authentication-manager-ref="authenticationManager"
entry-point-ref="http403EntryPoint"
>
<sec:form-login
login-processing-url="/login"
password-parameter="password"
username-parameter="username"
/>
<!-- <sec:custom-filter ref="tokenCreatorAndValidator" position="FORM_LOGIN_FILTER" /> -->
<sec:intercept-url pattern="/**"
method="POST"
access="ROLE_USER"
/>
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider user-service-ref="authenticatorDAO">
</sec:authentication-provider>
</sec:authentication-manager>
<bean id="http403EntryPoint"
class="com.app.login.RestAuthenticationEntryPoint" />
code for AuthenticationEntryPoint is given below.
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint{
#Override
public void commence( HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException ) throws IOException{
System.out.println("in RestAuthenticationEntrypoint\n--------------------------------------\n");
response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" );
}
}
can anybody tell me what I m doing wrong here?
Sorry cannot post comments hence posting this as answer.
Check if ExceptionTranslationFilter is getting called in your exiting configuration.
OR
Did you injected http403EntryPoint in ExceptionTranslationFilter?
<bean id="etf" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="http403EntryPoint"/>
</bean
>
I am trying to send an email but before I was getting a nullpointerexception error which was due to mailSender not getting set correctly, now I edited the code as it is shown below and I am not getting any exception but the code breaks at the line
MimeMessage message = mailSender.createMimeMessage();
Here is my code (both sendMail() and addNewAlarm() are inside the same class "ElementService"):
public class ElementService implements ApplicationContextAware {
private ApplicationContext ac;
public void sendMail(String toAddress, String subject, String body) throws Exception{
JavaMailSender mailSender = (JavaMailSender) ac.getBean("mailSender");
MimeMessage message = mailSender.createMimeMessage();
try{
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom("xxx#gmail.com");
helper.setTo(toAddress);
helper.setSubject(subject);
helper.setText(body);
}catch (MessagingException e) {
throw new MailParseException(e);
}
try{
mailSender.send(message);
}
catch(Exception e){
throw e;
}
}
//I want an email to be sent every 30 seconds
#Scheduled(fixedDelay = 30*1000)
public void function2RepeatEvery30Seconds()
{
MailService mailer = (MailService) ac.getBean("mailService");
mailer.sendMail("xxx#hotmail.com","subject","body");
//does other stuff..
}
#Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
this.ac = ac;
}
}
These are the beans in my xml:
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<!-- SMTP settings -->
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="***#gmail.com" />
<property name="password" value="*****" />
<property name="javaMailProperties">
<!-- additional properties specific to JavaMail -->
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
In debug mode I can see that mailSender has been set according to the properties shown on the mailSender bean.
I finally did it!! Thanks to Serge Ballesta of course. I should have been using log4j all along... I researched the Exception MessageRemovedIOException and I found this post java.lang.NoClassDefFoundError: com/sun/mail/util/MailLogger for JUnit test case for Java mail where there is a suggestion in the comments to change
<dependency> <groupId>javax.mail</groupId> <artifactId>javax.mail-api</artifactId> <version>1.5.2</version> </dependency>
to
<dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.5.2</version> </dependency>
I also had to change this:
<prop key="mail.smtp.starttls.enable">true</prop>
to this:
<prop key="mail.smtp.starttls.enable">false</prop>
Thank you very much for your time and advice #Serge Ballesta!
Ok, obviously the mailSender is null which causes the error. My guess would be that your #Autowired annotation is not processed. Do you have AutowiredAnnotationBeanPostProcessor registered? You can do that for example by using <context:annotation-config /> in your Spring configuration.
Other option (without using #Autowired) is to manually specify the dependency on mailSender in your mailService bean definition like so:
<bean id="mailService" class="gr.mobics.allweb.service.MailService" scope="singleton">
<property name="mailSender" ref="mailSender" />
</bean>
I have not tested this, but it seems like this is the cause of your problem. If these solutions don't work you, leave a comment and I'll try to update the answer.
i'm working with Spring batch, i've done the batch job, configured with an xml file,
i also put all the Quartz configuration in that xml file, (the trigger, schedulerFactoryBean and jobDetail); this is a java project, and i'm trying to load the application context, as an stand alone in a main class; as far as the documentation says, this should make Quartz to start running and is doing it, the problem is when the job runs with the trigger and calls the service, is like all the Autowired beans hadn’t had been loaded, so is giving me an NullpointerException…
this is the code that the job calls after the trigger is fired, and when the JobParametersBuilder is created is when everything crash, Quartz still running though...
could someone helpme with this?
//class called by the job
public class MainJobClass {
private static Logger log = Logger.getLogger(MainJobClass.class);
#Autowired
private SimpleJobLauncher launcher;
#Autowired
private Job job;
public void executeJob(){
try{
log.info("***** Staring job......");
JobParametersBuilder builder = new JobParametersBuilder();
builder.addDate("date", new Date());
builder.addString("sendEmailJob", "Send email to approvers");
JobParameters parameters = builder.toJobParameters();
launcher.run(job, parameters);
}catch(Exception e){
log.error("Error on executing job"+e.fillInStackTrace());
}
}
public void setLauncher(SimpleJobLauncher launcher) {
this.launcher = launcher;
}
public void setJob(Job job) {
this.job = job;
}
simple main method calling App context:
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("/com/ge/grt/email/grt_email_send.xml");
}
error line:
INFO [DefaultQuartzScheduler_Worker-1] (MainJobClass.java:29) - ***** Staring job......
ERROR [DefaultQuartzScheduler_Worker-1] (MainJobClass.java:40) - Error on executing jobjava.lang.NullPointerException
this are the Quartz beans on the xml file:
<!-- Scheudler Factory bean, the job will run when the context is loaded -->
<bean id="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="beanTrigger"></ref>
</list>
</property>
</bean>
<!-- definition of the trigger -->
<!-- defining the execution date: (once every week on monday at 8:00 AM) -->
<bean id="beanTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="jobDetail" />
<property name="misfireInstructionName" value="MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"/>
<!-- <property name="cronExpression" value="0 0 8 ? * MON" /> -->
<property name="cronExpression" value="0 0/1 * * * ?" />
</bean>
<!-- definiton of job detail bean -->
<bean id="jobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="mainJobClass" />
<property name="targetMethod" value="executeJob" />
<property name="concurrent" value="false"></property>
</bean>
Try org.springframework.scheduling.quartz.JobDetailBean along with jobDataAsMap for job class DI
Ex:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html#scheduling-quartz-jobdetail