spring security + oauth2 + mysql + database authentication - mysql

I am working on spring security with oauth2 authentication. Previously for client details service in authorization server I was using in-memory mechanism and it was working perfectly.And now I want to use database for client details service. I am using Mysql database. Kindly provide some solution for configuring client details service for database.
I am sharing my authorization server configuration class:
#SpringBootApplication
#Controller
#SessionAttributes("authorizationRequest")
#EnableResourceServer
public class AuthServerApplication extends WebMvcConfigurerAdapter {
#RequestMapping("/user")
#ResponseBody
public Principal user(Principal user) {
return user;
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/oauth/confirm_access").setViewName("authorize");
}
public static void main(String[] args) {
SpringApplication.run(AuthServerApplication.class, args);
}
#Configuration
protected static class CorsFilterConfig {
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
// we want this to run before the SpringSecurityFilterChain which we set at 50 in properties
// anything less than 50 will work
bean.setOrder(0);
return bean;
}
}
#Configuration
//#Order(-20)
protected static class LoginConfig extends WebSecurityConfigurerAdapter{
#Autowired
#Qualifier("authenticationManager")
private AuthenticationManager authenticationManager;
#Autowired
private CustomUserDetailsService userDetailsService;
/**
* '/oauth/authorize' is AuthorizationEndPoint and it's used to service requests for authorization.
* '/oauth/confirm_access' endpoint - User approval for Grants here.
* Authorization endpoint /oauth/authorize (or its mapped alternative) should be protected using Spring Security so that it is only accessible to authenticated users
* Authorization endpoint is used to grant authorization to client application
* The TokenEndPoint is protected by default by spring oauth in the #Configuration support using HttpBasicAuthentication of the client secret
*/
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin() // Allows users to authenticate with form based login
.loginPage("/login") // location of log in page
.permitAll() // grant access to all users to access to our log in page
.and()
.requestMatchers()
.antMatchers("/login","/oauth/authorize", "/oauth/confirm_access") // These URL's any user can access
.and()
.authorizeRequests().anyRequest().authenticated(); // Any other request to our application requires the user to be authenticated
// .and()
// .rememberMe()
// .key("uniqueAndSecret")
// .tokenValiditySeconds(86400);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.parentAuthenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
// auth
// .inMemoryAuthentication()
// .withUser("roy").password("spring").roles("USER");
}
}
/*
* EnableAuthorizationServer annotation is used to configure the oauth2.0 Authorization Server Mechanism together with any beans that implement AuthorizationServerConfigurer
*
*/
#Configuration
#EnableAuthorizationServer
protected static class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManager")
private AuthenticationManager authenticationManager;
#Autowired
private ApplicationContext context;
#Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory(
new ClassPathResource("keystore.jks"), "suleman123".toCharArray())
.getKeyPair("resourcekey");
converter.setKeyPair(keyPair);
return converter;
}
// #Bean
// public DataSource dataSource(){
// //jdbc:hsqldb:mem:testdb
// EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
// EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.HSQL)
// .addScript("classpath:schema.sql")
// .addScript("classpath:data.sql")
// .build();
// return db;
// }
/*
* A configurer that defines the client details service.
* ClientDetailsServiceConfigurer is used to define an in-memory or JDBC implementation of the client details service.
*
* A authorization code is obtained by the OAuth client by directing the end-user to an authorization page where the user can enter
* his/her credentials, resulting in a redirection from the provider authorization server back to the OAuth client with the authorization code
*
* We registered the client and authorized for the 'authorization_code', 'refresh_token', 'password' grant types
*
*/
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// clients.inMemory()
// .withClient("acme") //(required) the client id.
// .secret("acmesecret") //(required for trusted clients) the client secret, if any.
// .authorizedGrantTypes("authorization_code", "refresh_token",
// "password") // Grant types that the client is to use to obtain an access token
// .accessTokenValiditySeconds(5)
// .scopes("openid") // scope to which the client is limited
// .autoApprove(true);
DriverManagerDataSource dataSource = (DriverManagerDataSource)context.getBean("dataSource");
clients.jdbc(dataSource);
}
/**
* Defines the authorization and token end point and token services
*/
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter());
}
/**
* defines the security constraints on the token end point
*/
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
//
oauthServer.tokenKeyAccess("permitAll()") // It open the access to public key exposed by the authorization server on the end point /oauth/token_key
.checkTokenAccess("isAuthenticated()"); // check it is authenticated or not
}
}
}

Related

How do I make a JMS ObjectMessage for a Unit Test?

I'm trying to write a unit test for an MDB. The goal of my test is to make sure that the logic in the MDB can identify the correct type of object in the ObjectMessage and process it. However, I can't figure out how to make an ObjectMessage so I can test it. I keep getting null pointer exceptions.
Here is my unit test:
/**
* Test of the logic in the MDB
*/
#RunWith(JMockit.class)
#ExtendWith(TimingExtension.class)
class MDBTest
{
protected MyMDB mdb;
#BeforeEach
public void setup() throws NamingException, CreateHeaderException, DatatypeConfigurationException, PropertiesDataException
{
mdb = new MyMDB();
}
/**
* Test the processing of the messages by the MDB
*/
#Test
void testReceivingMessage() throws JMSException, IOException
{
MyFirstObject testMsg = getTestMessage();
ObjectMessage msg = null;
Session session = null;
new MockUp<ObjectMessage>()
{
#Mock
public void $init()
{
}
#Mock
public Serializable getObject()
{
return testMsg;
}
};
new MockUp<Session>()
{
#Mock
public void $init()
{
}
#Mock
public ObjectMessage createObjectMessage(Serializable object)
{
return msg;
}
};
// !!!! Null pointer here on Session !!!!
ObjectMessage msgToSend = session.createObjectMessage(testMsg);
mdb.onMessage(msgToSend);
assertEquals(1, mdb.getNumMyFirstObjectMsgs());
}
/**
* Create a Test Message
*
* #return the test message
* #throws IOException
*/
protected MyFirstObject getTestMessage) throws IOException
{
MyFirstObject myObj = new MyFirstObject();
myObj.id = 0123;
myObj.description = "TestMessage";
return myObj;
}
}
I feel like I should be able to initialize Session somehow, but I need to do it without using an additional library like Mockrunner.
Any suggestions?
I would try to address this in a different style. Provide a mock client, that will just mock the right API.
We should mock only a set of functions required for message retrieval and processing but that means we might have to provide a custom implementation for some of the APIs available in the EJB/JMS library. The mock client will have a function to push messages on a given topic/queue/channel, message can be simple String.
A simple implementation might look like this, in this other methods have been omitted for simplicity.
// JMSClientImpl is an implementation of Connection interface.
public class MyJmsTestClient extends JMSClientImpl{
Map<String, String> channelToMessage = new ConcurrentHashMap<>();
public Map<String, String> getMessageMap(){
return channelToMessage;
}
public void enqueMessage(String channel, String message){
channelToMessage.put(channe, message);
}
#Override
public Session createSession(){
return new MyTestSession(this);
}
}
// A class that implements some of the methods from session interface
public MyTestSession extends SessionImpl{
private MyJmsTestClient jmsClient;
MyTestSession(MyJmsTestClient jmsClient){
this.jmsClient = jmsClient;
}
// override methods that fetches messages from remote JMS
// Here you can just return messages from MyJmsTestClient
// override other necessary methods like ack/nack etc
MessageConsumer createConsumer(Destination destination) throws JMSException{
// returns a test consume
}
}
A class that implements methods from MessageConsumer interface
class TestMessageConsumer extends MessageConsumerImpl {
private MyJmsTestClient jmsClient;
private Destination destination;
TestMessageConsumer(MyJmsTestClient jmsClient, Destination destination){
this.jmsClient = jmsClient;
this.destination = destination;
}
Message receive() throws JMSException{
//return message from client
}
}
There's no straight forward, you can see if there're any library that can provide you embedded JMS client feature.

how to get Keycloak access token and store it in db for spring boot?

i want get the access token first and store the access token generated by keycloak during login... in my db. i am using spring boot .
this is the code that i tried for getting the access token ..but result is nothing.... have a better solution?
..
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String getCustomers()
{
HttpServletRequest request =((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes())
.getRequest();
KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) request.getUserPrincipal();
KeycloakPrincipal principal = (KeycloakPrincipal) token.getPrincipal();
KeycloakSecurityContext session = principal.getKeycloakSecurityContext();
AccessToken accessToken = session.getToken();
String a = principal.getName();
String username = accessToken.getPreferredUsername();
String realmName = accessToken.getIssuer();
AccessToken.Access realmAccess = accessToken.getRealmAccess();
String s = session.getToken().toString();
System.out.println(s);
return realmName;
.. }
i expect to get the access token generated by keycloak and store it in db.
#KeycloakConfiguration class SecurityConfig extends
KeycloakWebSecurityConfigurerAdapter {
/**
* Registers the KeycloakAuthenticationProvider with the authentication manager.
*/
#Autowired public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception { KeycloakAuthenticationProvider
keycloakAuthenticationProvider=keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new
SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider); }
/**
* Defines the session authentication strategy.
*/
#Bean
#Override protected SessionAuthenticationStrategy
sessionAuthenticationStrategy() { return new
RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); }
#Bean public KeycloakConfigResolver keycloakConfigResolver() { return new
KeycloakSpringBootConfigResolver(); }
#Override protected void configure(HttpSecurity http) throws Exception {
super.configure(http); http .authorizeRequests()
.antMatchers("/login*").hasRole("springrole") .anyRequest().permitAll(); } }
this is my keycloak configuration..
U need login to keycloak, i see u just call custom "/login" and expect keycloak principal.

CAS difference between Candidate/Registered and Sorted and registered Authentication Handler

I am having a blocker situation with CAS 6.0.x and I cant get past it. I Am unable to log in with a UsernamePasswordCredential. I have even removed all actual checks, and simply return a credential.
Here is the coide:
public class MyDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
public MyDatabaseAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order, DataSource dataSource) {
super(name, servicesManager, principalFactory, order, dataSource);
}
#Override
protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential, String originalPassword) throws GeneralSecurityException, PreventedException {
return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null);
}
#Override
public boolean supports(final Credential credential) {
return true;
}
}
Here is my config:
#Configuration("My6CasConfiguration")
public class My6CasConfiguration implements AuthenticationEventExecutionPlanConfigurer {
#Autowired
#Qualifier("principalFactory")
private PrincipalFactory principalFactory;
#Bean
public AuthenticationHandler getMyJdbcAuthenticationHandler() {
return new MyDatabaseAuthenticationHandler("MYJDBCAuthenticationManager",
servicesManager,
principalFactory,
0,
customDataSource());
}
#Override
public void configureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) {
plan.registerAuthenticationHandler(getMyJdbcAuthenticationHandler());
}
}
This is what I am getting in the logs:
[36m2019-06-02 11:07:38,544 DEBUG [org.apereo.cas.authentication.DefaultAuthenticationEventExecutionPlan] - <Candidate/Registered authentication handlers for this transaction are [[org.apereo.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler#277fd34b, com.xxx.cas.handler.MyDatabaseAuthenticationHandler#58b0ac93, org.apereo.cas.adaptors.x509.authentication.handler.support.X509CredentialsAuthenticationHandler#41078c16]]>^[[m
[[36m2019-06-02 11:07:38,544 DEBUG [org.apereo.cas.authentication.DefaultAuthenticationEventExecutionPlan] - <Sorted and registered authentication handler resolvers for this transaction are [[org.apereo.cas.authentication.handler.ByCredentialSourceAuthenticationHandlerResolver#663cfaa1, org.apereo.cas.authentication.handler.RegisteredServiceAuthenticationHandlerResolver#272f62cc]]>^[[m
[[36m2019-06-02 11:07:38,545 DEBUG [org.apereo.cas.authentication.DefaultAuthenticationEventExecutionPlan] - <Authentication handler resolvers for this transaction are [[org.apereo.cas.authentication.handler.ByCredentialSourceAuthenticationHandlerResolver#663cfaa1, org.apereo.cas.authentication.handler.RegisteredServiceAuthenticationHandlerResolver#272f62cc]]>^[[m
[[1;31m2019-06-02 11:07:38,549 ERROR [org.apereo.cas.authentication.PolicyBasedAuthenticationManager] - <Authentication has failed. Credentials may be incorrect or CAS cannot find authentication handler that supports [UsernamePasswordCredential(username=asdf, source=MYJDBCAuthenticationManager)] of type [UsernamePasswordCredential]. Examine the configuration to ensure a method of authentication is defined and analyze CAS logs at DEBUG level to trace the authentication event.>^[[m
[[1;31m2019-06-02 11:07:38,550 ERROR [org.apereo.cas.authentication.PolicyBasedAuthenticationManager] - <[MYJDBCAuthenticationManager]: [warnings is marked #NonNull but is null]>
What am I doing wrong that this is not working? And what is that difference between Candidate/Registered, Sorted/Registered, and handler resolvers?
The act that my custom class only shows up in the first, makes me think I have configured something wrong.
Any Ideas?

Spring Integration - no response on reply channel

This is a follow up question to Spring Integration Executor Channel using annotations code sample.
System diagram is attached .
I am trying to test the box highlighted in red by posting a message into 'Common channel' and reading from REPLY_CHANNEL set in the msg.
'Common channel' is a publish subscribe channel.
REPLY_CHANNEL is a QueueChannel.
Since this is a JUnit test, I have mocked jdbcTemplate, datasource and the Impl to ignore any DB calls.
My issue is:
When I post a message onto 'Common Channel', I do not receive any message on the REPLY_CHANNEL. The junit keeps waiting for a response.
What should I change to get a response on the REPLY_CHANNEL?
#RunWith(SpringRunner.class)
#SpringBootTest
#ContextConfiguration(loader = AnnotationConfigContextLoader.class) --------- 1
#ActiveProfiles("test")
public class QueuetoQueueTest {
#Configuration
static class ContextConfiguration { ------------------------------------- 2
#Bean(name = "jdbcTemplate")
public JdbcTemplate jdbcTemplate() {
JdbcTemplate jdbcTemplateMock = Mockito.mock(JdbcTemplate.class);
return jdbcTemplateMock;
}
#Bean(name = "dataSource")
public DataSource dataSource() {
DataSource dataSourceMock = Mockito.mock(DataSource.class);
return dataSourceMock;
}
#Bean(name = "entityManager")
public EntityManager entityManager() {
EntityManager entityManagerMock = Mockito.mock(EntityManager.class);
return entityManagerMock;
}
#Bean(name = "ResponseChannel")
public QueueChannel getReplyQueueChannel() {
return new QueueChannel();
}
//This channel serves as the 'common channel' in the diagram
#Bean(name = "processRequestSubscribableChannel")
public MessageChannel getPublishSubscribeChannel() {
return new PublishSubscribeChannel();
}
}
#Mock
DBStoreDaoImpl dbStoreDaoImpl;
#Test
public void testDBConnectivity() {
Assert.assertTrue(true);
}
#InjectMocks -------------------------------------------------------------- 3
StoretoDBConfig storetoDBConfig = new StoretoDBConfig();
#Autowired
#Qualifier("ResponseChannel")
QueueChannel ResponseChannel;
#Autowired
#Qualifier("processRequestSubscribableChannel")
MessageChannel processRequestSubscribableChannel;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void outboundtoQueueTest() {
try {
when(dbStoreDaoImpl.storeToDB(any()))
.thenReturn(1); ----------------------------------------------- 4
//create message
Message message = (Message<String>) MessageBuilder
.withPayload("Hello")
.setHeader(MessageHeaders.REPLY_CHANNEL, ResponseChannel)
.build();
//send message
processRequestSubscribableChannel.send(message);
System.out
.println("Listening on InstructionResponseHandlertoEventProcessorQueue");
//wait for response on reply channel
Message<?> response = ResponseChannel.receive(); ----------------------- 5
System.out.println("***************RECEIVED: "
+ response.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Load 'ContextConfiguration' for JUnit so that DB is not accessed.
This is how you load custom configuration in JUnit as per https://spring.io/blog/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles
Inside the config class, we mock jdbcTemplate, dataSource, entityManager and define the 'common channel' on which the request is posted and ResponseChannel.
Inject jdbcTemplate, dataSource mock into StoretoDBConfig so that the DB is not hit
Mock DaoImpl class so that DB calls are ignored
The test blocks here because there is no response on the REPLY_CHANNEL
UPDATED CODE:
Code inside 5 (the class that reads from common channel):
#Configuration
class HandleRequestConfig {
//Common channel - refer diagram
#Autowired
PublishSubscribeChannel processRequestSubscribableChannel;
//Step 9 - This channel is used to send queue to the downstream system
#Autowired
PublishSubscribeChannel forwardToExternalSystemQueue;
public void handle() {
IntegrationFlows.from("processRequestSubscribableChannel") // Read from 'Common channel'
.wireTap(flow->flow.handle(msg -> System.out.println("Msg received on processRequestSubscribableChannel"+ msg.getPayload())))
.handle(RequestProcessor,"validateMessage") // Perform custom business logic - no logic for now, return the msg as is
.wireTap(flow->flow.handle(msg -> System.out.println("Msg received on RequestProcessor"+ msg.getPayload())))
.channel("forwardToExternalSystemQueue"); // Post to 'Channel to another system'
}
}
//Code inside step 8 - 'Custom Business Logic'
#Configuration
class RequestProcessor {
public Message<?> validateMessage(Message<?> msg) {
return msg;
}
}
WHAT I AM TRYING TO ACHIEVE:
I have individual junit test cases for the business logic. I am trying to test that when the request is posted into the 'common channel', the response is received on 'channel to another system'.
Why I cannot use the original ApplicationContext: Because it connects to the DB, and I do not want my JUnit to connect to the DB or use an embedded database. I want any calls to the DB to be ignored.
I have set the reply channel to 'ResponseChannel', shouldn't the 'Custom Business Logic' send its response to 'ResponseChannel'?
If I have to listen on a different channel for the response, I am willing to do so. All I want to test is whether the message I am sending on 'common channel' is received on 'channel to other system'.
UPDATE 2:
Addressing Artem's questions.
Thankyou Artem for your suggestions.
Is 'HandlerRequestConfig' included in the test configuration? - We cannot directly call the handle() method. Instead I thought if I post on 'processRequestSubscribableChannel', the handle() method inside HandleRequestConfig will be invoked since it listens on the same channel. Is this wrong? How do I test HandleRequestConfig.handle() method then?
I added wiretap to the end of each step in HandleRequestConfig (code updated). I find that none of the wiretap message is printed. This means that the msg I am posting is not even reaching the input channel 'processRequestSubscribableChannel'. What am I doing wrong?
NOTE: I tried removing the 'processRequestSubscribableChannel' bean inside Configuration (so that the actual 'processRequestSubscribableChannel' in the applicationContext is used). I am getting an unsatisfied dependency error - Expected atleast 1 bean with configuration PublishSubscribeChannel.
Update 3: Posted details Artem requested.
#RunWith(SpringRunner.class)
#SpringBootTest
public class QueuetoQueueTest {
// Step 1 - Mocking jdbcTemplate, dataSource, entityManager so that it doesn't connect to the DB
#MockBean
#Qualifier("jdbcTemplate")
JdbcTemplate jdbcTemplate;
#MockBean
#Qualifier("dataSource")
public DataSource dataSource;
#MockBean
#Qualifier("entityManager")
public EntityManager entityManager;
#Bean(name = "ResponseChannel")
public PublishSubscribeChannel getReplyQueueChannel() {
return new PublishSubscribeChannel();
}
//Mocking the DB class
#MockBean
#Qualifier("dbStoreDaoImpl")
DBStoreDaoImpl dbStoreDaoImpl ;
//Inject the mock objects created above into the flow that stores data into the DB.
#InjectMocks
StoretoDBConfig storetoDBConfig = new StoretoDBConfig();
//Step 2 - Injecting MessageChannel used in the actual ApplicationContext
#Autowired
#Qualifier("processRequestSubscribableChannel")
MessageChannel processRequestSubscribableChannel;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void outboundtoQueueTest() {
try {
when(dbStoreDaoImpl.storeToDB(any()))
.thenReturn(1);
//create message
Message message = (Message<?>) MessageBuilder
.withPayload("Hello")
.build();
//send message - this channel is the actual channel used in ApplicationContext
processRequestSubscribableChannel.send(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
ERROR I AM GETTING: The code tries to connect to the DB and throws an error.
UPDATE 1: Code inside StoretoDBConfig
#Configuration
#EnableIntegration
public class StoretoDBConfig {
#Autowired
DataSource dataSource;
/*
* Below code is irrelevant to our current problem - Including for reference.
*
* storing into DB is delegated to a separate thread.
*
* #Bean
* public TaskExecutor taskExecutor() {
* return new SimpleAsyncTaskExecutor();
* }
*
* #Bean(name="executorChannelToDB")
* public ExecutorChannel outboundRequests() {
* return new ExecutorChannel(taskExecutor());
* }
* #Bean(name = "DBFailureChannel")
* public static MessageChannel getFailureChannel() {
* return new DirectChannel();
* }
* private static final Logger logger = Logger
* .getLogger(InstructionResponseHandlerOutboundtoDBConfig.class);
*/
#Bean
public IntegrationFlow handle() {
/*
* Read from 'common channel' - processRequestSubscribableChannel and send to separate thread that stores into DB.
*
/
return IntegrationFlows
.from("processRequestSubscribableChannel")
.channel("executorChannelToDB").get();
}
}
CODE THAT STORES INTO DB ON THE SEPARATE THREAD:
#Repository
public class DBStoreDaoImpl implements DBStoreDao {
private JdbcTemplate jdbcTemplate;
#Autowired
public void setJdbcTemplate(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
#Override
#Transactional(rollbackFor = Exception.class)
#ServiceActivator(inputChannel = "executorChannelToDB")
public void storetoDB(Message<?> msg) throws Exception {
String insertQuery ="Insert into DBTable(MESSAGE) VALUES(?)";
jdbcTemplate.update(insertQuery, msg.toString());
}
}
Please, show us what is subscribed to that Common channel. Your diagram somehow is not related to what you show us. The code you demonstrate is not full.
The real problem with the replyChannel that something really has to send a message to it. If your flow is just one-way - send, store and nothing to return, - then you indeed won't get anything for this one. That's why would to show those channel adapters.
The best way to observe the message journey is to turn on debug logging for the org.springframework.integration category.
Although I see that you declare those channels as is in the ContextConfiguration and there is really no any subscribers to the getRequestChannel. Therefore nobody is going to consume your message and, of course, nobody is going to send you a reply.
Please, reconsider your test class to use the real application context. Otherwise it is fully unclear what you would like to achieve if you really don't test your flow...

In CAS Overlay, How to send user attributes

In CAS Overlay, How to return user attributes other than name to the clients in JAVA. I am using CAS Overlay project and storing the user details in Database.
Finally I am able to fetch the User Attributes of the Logged in User from the CAS Server to the client.
I am using CAS Overlay project version 5.0.0.RC1 and Spring Security 4.1.3.RELEASE.
Spring Client Configuration in WebSecurityConfigurerAdapter:
#Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(serviceUrl);
serviceProperties.setSendRenew(false);
return serviceProperties;
}
#Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
casAuthenticationProvider.setAuthenticationUserDetailsService(authenticationUserDetailsService());
casAuthenticationProvider.setServiceProperties(serviceProperties());
casAuthenticationProvider.setTicketValidator(cas30ServiceTicketValidator());
casAuthenticationProvider.setKey("an_id_for_this_auth_provider_only");
return casAuthenticationProvider;
}
#Bean
public Cas30ServiceTicketValidator cas30ServiceTicketValidator() {
return new Cas30ServiceTicketValidator(casServer);
}
#Bean
public AuthenticationUserDetailsService authenticationUserDetailsService(){
String[] role ={"user_role"};
return new GrantedAuthorityFromAssertionAttributesUserDetailsService(role);
}
#Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
casAuthenticationFilter.setAuthenticationManager(authenticationManager());
casAuthenticationFilter.setAuthenticationSuccessHandler(new CustomAuthenticationSuccessHandler());
casAuthenticationFilter.setAuthenticationFailureHandler(new CustomAuthenticationFailureHandler());
return casAuthenticationFilter;
}
#Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
casAuthenticationEntryPoint.setLoginUrl(casServerLogin);
casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
return casAuthenticationEntryPoint;
}
#Bean
public LogoutFilter requestSingleLogoutFilter (){
LogoutFilter logoutFilter = new LogoutFilter(casLogout,new SecurityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl("/j_spring_cas_security_logout");
return logoutFilter;
}
#Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter filter = new SingleSignOutFilter();
filter.setCasServerUrlPrefix(casServer);
filter.setIgnoreInitConfiguration(true);
return filter;
}
Configured the Database attribute repository on the CAS Server side as I was storing the user details in Database.
<code>
cas.authn.attributeRepository.jdbc.singleRow=true
cas.authn.attributeRepository.jdbc.requireAllAttributes=true
cas.authn.attributeRepository.jdbc.caseCanonicalization=NONE
cas.authn.attributeRepository.jdbc.queryType=OR
cas.authn.attributeRepository.jdbc.sql=SELECT * FROM users WHERE {0}
cas.authn.attributeRepository.jdbc.username=username
cas.authn.attributeRepository.jdbc.healthQuery=SELECT 1
cas.authn.attributeRepository.jdbc.isolateInternalQueries=false
cas.authn.attributeRepository.jdbc.url=jdbc:postgresql://localhost:5432/casdb
cas.authn.attributeRepository.jdbc.failFast=true
cas.authn.attributeRepository.jdbc.isolationLevelName=ISOLATION_READ_COMMITTED
cas.authn.attributeRepository.jdbc.dialect=org.hibernate.dialect.PostgreSQLDialect
cas.authn.attributeRepository.jdbc.leakThreshold=10
cas.authn.attributeRepository.jdbc.propagationBehaviorName=PROPAGATION_REQUIRED
cas.authn.attributeRepository.jdbc.batchSize=1
cas.authn.attributeRepository.jdbc.user=postgres
cas.authn.attributeRepository.jdbc.ddlAuto=update
cas.authn.attributeRepository.jdbc.password=postgres
cas.authn.attributeRepository.jdbc.autocommit=false
cas.authn.attributeRepository.jdbc.driverClass=org.postgresql.Driver
cas.authn.attributeRepository.jdbc.idleTimeout=5000
cas.authn.attributeRepository.jdbc.pool.suspension=false
cas.authn.attributeRepository.jdbc.pool.minSize=6
cas.authn.attributeRepository.jdbc.pool.maxSize=18
cas.authn.attributeRepository.jdbc.pool.maxIdleTime=1000
cas.authn.attributeRepository.jdbc.pool.maxWait=2000
cas.authn.attributeRepository.attributes.last_name=last_name
cas.authn.attributeRepository.attributes.first_name=first_name
cas.authn.attributeRepository.attributes.user_role=user_role
</code>
After these changes I was able to fetch the user attributes from CAS Server.