Spring for android RestTemplate object instantiation failed - spring-android

I am using spring for android in order to communicate with an existing RestAPI service. I am following this tutorial :
http://spring.io/guides/gs/consuming-rest-android/
I already have my android app, and I integrated this HttpRequestTask in one of my activities
private class HttpRequestTask extends AsyncTask<Void, Void, Greeting> {
protected Greeting doInBackground(Void... params) {
try {
final String url = "http://rest-service.guides.spring.io/greeting";
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Greeting greeting = restTemplate.getForObject(url, Greeting.class);
return greeting;
} catch (Exception e) {
Log.e("MainActivity", e.getMessage(), e);
}
return null;
}
protected void onPostExecute(Greeting greeting) {
....
}
}
and I then call execute method within the onStart method
#Override
protected void onStart() {
super.onStart();
new HttpRequestTask().execute();
}
Once I access this activity, the app crashes. I debuged it and found that the RestTemplate object fails in the instantiation line:
RestTemplate restTemplate = new RestTemplate();
I'am using spring 1.0.1.RELEASE core and rest jars.

The problem was that the added external jars are not deployed with the app at runtime, this link solves this issue:
How can I use external JARs in an Android project?

Related

Quarkus ExceptionMapper does not handle WebApplicationException

I'm trying to understand if this is a feature or a bug... :-)
For the below controller and exception mapper, for a rest client that will fail with a 401 response, I would expect the exception handler to be invoked for both cases. However it's not invoked for the WebApplicationException. Why is that and how are you meant to register an exception handler for them cases. This is using Quarkus version 0.21.2
#Path("/failable")
public class FailableResource {
#Inject
#RestClient
private SomeHttpClient httpClient;
#GET
#Path("fails")
#Produces(MediaType.TEXT_PLAIN)
public String fails() {
try {
return httpClient.someQuery();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
#GET
#Path("works")
#Produces(MediaType.TEXT_PLAIN)
public String works() {
try {
return httpClient.someQuery();
} catch (Exception e) {
e.printStackTrace();
throw new IllegalStateException("Not a WebApplicationException");
}
}
}
And the ExceptionMapper
#Provider
public class HandleMySillyError implements ExceptionMapper<Throwable> {
#Override
public Response toResponse(Throwable e) {
e.printStackTrace();
return Response.ok("Some handled response").build();
}
}
I found out when running in quarkus:dev mode the exception mapper is not invoked. It seems that this is caused by an exception mapper from quarkus that is only used in DEV mode (see https://github.com/quarkusio/quarkus/issues/7883).
I launched my code local as normal a normal java program, causing my exception handler to work as expected. Also when running the code on Openshift, my custom exception mapper is used as well.
note: I used quarkus version 1.8.3

RESTful API authentication using Spring Boot and LDAP

I have a requirement to build a RESTful API to authenticate users via LDAP(External LDAP) on Angular front end. I have tried various option but it doesn't seem to work. I guess it could be related to the way LDAP credentials are set.
Here is the LDAP config in application.properties.
ldap.enabled=true
####### LDAP ##############
ldap.urls=ldap://test.ldap.com:389/ <br>
ldap.base.dn=dc=comp,dc=company,dc=com<br>
ldap.username=cn=q123123,ou=health,ou=internal<br>
ldap.password=johnwick123<br>
ldap.user.dn.pattern=uid={0}<br>
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger LOG =
LoggerFactory.getLogger(WebSecurityConfig.class);
#Value("${ldap.urls}")
private String ldapUrls;
#Value("${ldap.base.dn}")
private String ldapBaseDn;
#Value("${ldap.username}")
private String ldapSecurityPrincipal;
#Value("${ldap.password}")
private String ldapPrincipalPassword;
#Value("${ldap.user.dn.pattern}")
private String ldapUserDnPattern;
#Value("${ldap.enabled}")
private String ldapEnabled;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().fullyAuthenticated().and().formLogin();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
try {
auth.ldapAuthentication().contextSource().url(ldapUrls + ldapBaseDn).managerDn(ldapSecurityPrincipal)
.managerPassword(ldapPrincipalPassword).and().userDnPatterns(ldapUserDnPattern);
} catch (Exception ex) {
LOG.error("Handle exception here");
throw ex;
}
}
#Bean
public static PropertySourcesPlaceholderConfigurer
PropertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Input to Spring Boot API is { "username":, "password": }
Output from Spring Boot API is { "status": 200, "message": "user authenticated"}

Spring-security/Grails app - Custom WebSecurity configurations not getting called

My project is based on Grail 2.5.6 and Spring plugins. I'm trying to create a custom auth provider, filter and token extending their respective basic classes.
this.getAuthenticationManager().authenticate(authRequest)
In my filter the authentication manager is always null. So, it throws cannot invoke authenticate() on a null object. When I debug on the authenticationManager, it lists other provider names but my custom one.
Here is my custom web security config
#Configuration
#EnableGlobalMethodSecurity(securedEnabled=true)
public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
OrbisAuthenticationProvider orbisAuthenticationProvider
public CustomWebSecurityConfig() {
super()
log.debug "configure custom security"
print("configure custom security")
}
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
print("configure method 1")
log.debug "configure method 1"
auth.authenticationProvider(orbisAuthenticationProvider)
}
#Bean(name= BeanIds.AUTHENTICATION_MANAGER)
#Override
AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean()
}
#Bean
OrbisAuthenticationFilter orbisAuthenticationProvider() throws Exception {
log.debug "orbis Authentication provider"
OrbisAuthenticationProvider orbisAuthenticationProvider = new OrbisAuthenticationProvider(authenticationManagerBean())
return orbisAuthenticationProvider
}
#Bean
#Autowired
public OrbisAuthenticationFilter orbisAuthenticationFilter() throws Exception {
print("configure orbis filtr")
OrbisAuthenticationFilter oaf = new OrbisAuthenticationFilter()
oaf.setAuthenticationManager(authenticationManagerBean())
oaf.setFilterProcessesUrl("j_orbis_security_check")
oaf.setUsernameParameter("email")
oaf.setPasswordParameter("password")
oaf.setAuthenticationSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler()
.setDefaultTargetUrl("/oauth/authorize"))
oaf.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler()
.setDefaultFailureUrl("/loginWithOrbis"))
oaf.afterPropertiesSet()
return oaf
}
}
On debugging, it doesn't look like any of these methods are getting called. The annotations don't seem enough to get picked up. I had tried #ComponentScan too.
Do I have to inject this security config somewhere? How do I get authManager to be available in my filter?
OrbisAuthFilter
class OrbisAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
// #Autowired
OrbisAuthenticationProvider orbisAuthenticationProvider
OrbisAuthenticationFilter() {
super("/j_orbis_security_check")
orbisAuthenticationProvider = new OrbisAuthenticationProvider()
}
void afterPropertiesSet() {
assert authenticationManager != null, 'authenticationManager must be specified'
}
#Override
Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
String username = request.getParameter("email")
String password = request.getParameter("password")
String accessCode = request.getParameter("accessCode")
OrbisAuthenticationToken authRequestForAuthentication = new OrbisAuthenticationToken(username, password, accessCode)
// This throws error because getAuthenticationManager returns null
// authRequestForAuthentication = this.getAuthenticationManager.authenticate(authRequestForAuthentication)
//This works if I instantiate the orbis provider object in the constructor
authRequestForAuthentication = this.orbisAuthenticationProvider.authenticate(authRequestForAuthentication)
SecurityContextHolder.getContext().setAuthentication(authRequestForAuthentication)
return authRequestForAuthentication
}
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
}
#Override
#Autowired
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
}
OrbisAuthProvider
class OrbisAuthenticationProvider implements AuthenticationProvider {
#Override
Authentication authenticate(Authentication authentication) throws AuthenticationException {
OrbisAuthenticationToken orbisAuth = (OrbisAuthenticationToken) authentication
String username = orbisAuth.principal
String password = orbisAuth.credentials
String orbisAccessCode = orbisAuth.orbisAccessCode
def urlToUse = 'https://coopstatus.neu.edu/sail_api/full.aspx?' + 'ac=' + orbisAccessCode + '&e='+ username + '&p=' + password
HttpClient httpClient = DefaultHttpClient.newInstance()
HttpGet getRequest = new HttpGet(urlToUse)
HttpResponse httpResponse = httpClient.execute(getRequest)
JSONObject orbisResponse = new JSONObject(httpResponse.getEntity().getContent().getText())
// if(orbisResponse.get("IsFound")) {
// //Return error not authenticated
// }
Collection<GrantedAuthority> orbisUserGrantedAuthorities = getLDAPUserAuthorities(orbisResponse.get("Email"))
orbisAuth = new OrbisAuthenticationToken(username, password, orbisAccessCode, orbisUserGrantedAuthorities)
return orbisAuth
}
private Collection<GrantedAuthority> getLDAPUserAuthorities(String username) {
LDAPUserDetails currentLdapUserDetails
try {
currentLdapUserDetails = new LDAPUserDetailsService().loadUserByOrbisUsername(username)
log.debug currentLdapUserDetails
} catch(org.springframework.security.core.userdetails.UsernameNotFoundException e) {
log.error("User " + username + " not found in ldap", e)
}
Collection<GrantedAuthority> authorities = new ArrayList<>()
for (String authority : currentLdapUserDetails.authorities) {
authorities.add(new SimpleGrantedAuthority(authority))
}
return authorities
}
#Override
public boolean supports(Class<?> authentication) {
return (OrbisAuthenticationToken.class
.isAssignableFrom(authentication));
}
}
Resources.groovy
import edu.neu.security.OrbisAuthenticationFilter
import edu.neu.security.OrbisAuthenticationProvider
beans = {
userDetailsService(edu.neu.security.LDAPUserDetailsService)
orbisAuthenticationProvider(OrbisAuthenticationProvider)
orbisAuthenticationFilter(OrbisAuthenticationFilter) {
orbisAuthenticationProvider = ref("orbisAuthenticationProvider")
requiresAuthenticationRequestMatcher = ref('filterProcessUrlRequestMatcher')
// This throws error during startup. Unable to init bean
// authenicationManager = ref("authenicationManager")
}
myOAuth2ProviderFilter(OAuth2ProviderFilters) {
//grailsApplication = ref('grailsApplication')
// properties
}
}
I followed some of the concepts from this project: https://github.com/ppazos/cabolabs-ehrserver/
Even if the whole process is executed and securityContext is set with authenticated, when I hit oauth/authorize to get Authorization_Code, it redirects back to '/login/auth'. It still doesn't know that a user is already authenticated.
When you add an authentication provider to the AuthenticationManagerBuilder bean (which comes from AuthenticationConfiguration), the authentication manager bean you declare is not used.
Try:
#Configuration
#EnableGlobalMethodSecurity(securedEnabled=true)
public class CustomWebSecurityConfig {
OrbisAuthenticationProvider lwoAuthProvider;
public CustomWebSecurityConfig() {
//
}
#Bean(name= BeanIds.AUTHENTICATION_MANAGER)
AuthenticationManager authenticationManagerBean() throws Exception {
return new ProviderManager(Arrays.asList(lwoAuthProvider));
}
Your AuthenticationManager bean should get picked up and will be used for method security. You can also #Autowire it in your filter if it is being managed by Spring, or #Autowire it in the #Configuration class that instantiates your filter.
NOTE: the above class WILL NOT create any of the Spring Security filters.
(The filter chain wasn't being created anyway - you didn't annotate your class with #EnableWebSecurity)

How to configure distributed Topic or Queue using Apache MQ with JNDI properties and also embeded MQ in applicaiton server

We are moving from weblogic jms to activemq. We put all the activemq required jar files into our application classpath and created one properties file which contains activemq url and connectionfactory details like below:
java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://localhost:61616
connectionFactoryNames=TestTopicConnectionFactory
topic.mq/TestTopic=TestTopic
During server startup we are loading this properties file as below and starting the MQ broker srevice.
public TestServlet extends HttpServlet {
private MQStartup mqStartup = null;
#Override
public void init(ServletConfig config)
throws ServletException {
super.init(config);
mqStartup = new MQStartup();
mqStartup.startBrokerService();
}
}
public class MQStartup {
private final String bindAddress;
private BrokerService broker = new BrokerService();
public MQStartup(){
MQContext context = new MQContext();
context.loadJndiProperties();
bindAddress = ActiveMQContext.getProperty("java.naming.provider.url");
}
public void startBrokerService() {
broker.addConnector(bindAddress);
broker.start();
}
public void stopBrokerService() {
try {
broker.stop();
}catch (Exception e) {
logger.error("Unable to stop the MQ Broker service " +e);
}
}
}
public class MQContext {
private static final Object singletonLock = new Object();
static Context context = null;
static Properties properties = null;
private boolean loaded = false;
public void loadJndiProperties() {
try {
if (!loaded) {
synchronized (singletonLock) {
URL url = getClass().getClassLoader().getResource("jda-activemq-jndi.properties");
properties = new Properties();
properties.load(url.openStream());
context = new InitialContext(properties);
loaded = true;
}
}
} catch (IOException | NamingException ie) {
logger.error("Failed to load apachemq jndi", ie);
}
}
public static Context getContext() {
return context;
}
public static Properties getProperties() {
return properties;
}
public static String getProperty(String propertyName) {
return properties.getProperty(propertyName);
}
}
In implementation class for producing message we are getting the mq connectionfactory lile below:
TopicConnectionFactory factory = (TopicConnectionFactory) MQContext.getContext().lookup("<topicFactoryName>");
this.topicConnection = factory.createTopicConnection();
this.topicConnection.start();
and then creating topic session and using publisher.publish("message");
But the problem here is we have 3 application instance in cluster and for these 3 instance we have 3 embeded activemq broker service.
When I am producing one message and sending in instance1(suppose webserver is hitting instance1) this message is not consumed by other2 instance.
I googled there is some networkconnector configuration can be helped. But the problem is we are using JNDI and MQ is not a separate installation.
Is there any way to do this with embeded MQ and with JNDI.
Note: In weblogic we have UniformDistributedTopic type of topic which helps to achive the above but in MQ it seems we don't have this kind of topic type.

Spring AMQP: Register BlockedListener to Connection

I am trying to implement Blocked Listeners to RabbitMQ using RabbitTemplate of Spring AMQP. In my code i am using Spring-amqp 1.1.3 version jar file, whereas i have looked into the version 1.3.1 as well and this is unsupported in this version also. Does anyone know if i am missing any version which has support of registering Blocked listeners to the new connections in RabbitMQ. Or if is there any future release of spring amqp to support this feature.
Example Code:
Connection connection = factory.newConnection();
connection.addBlockedListener(new BlockedListener() {
#Override
public void handleUnblocked() throws IOException {
System.out.println("Connection is Unblocked");
}
#Override
public void handleBlocked(String arg0) throws IOException {
System.out.println("Connection Blocked");
}
});
com.rabbitmq.client.Channel channel = connection.createChannel();
This is not currently available out of the box; please feel free to open an Improvement JIRA Issue.
However, you can add a Spring AMQP ConnectionListener to the CachingConnectionFactory...
connectionFactory.addConnectionListener(new ConnectionListener() {
#Override
public void onCreate(Connection connection) {
Channel channel = connection.createChannel(false);
channel.getConnection().addBlockedListener(new BlockedListener() {
#Override
public void handleUnblocked() throws IOException {
}
#Override
public void handleBlocked(String reason) throws IOException {
}
});
try {
channel.close();
}
catch (IOException e) {
}
}
#Override
public void onClose(Connection connection) {
}
});
It will be called even if the connection has already been established when you add the listener.