Is there a way of adding login security to the admin servlet?
Seems like in V0.7 you could add the following two to your yaml file :
adminUsername: user1234
adminPassword: pass5678
However I tried that in the latest version (0.9.2) and it gives me an error saying :
server.yaml has an error:
* Unrecognized field at: server.adminConnectors.[0].adminUsername
Did you mean?:
- soLingerTime
- bindHost
- idleTimeout
- useServerHeader
- useDateHeader
[14 more]
This is what I have :
adminConnectors:
- type: http
port: 9180
adminUsername: user1234
adminPassword: pass5678
I run an app on Heroku which only allows the application to make a single port available. I attach the AdminServlet to the main HTTP port (8080) with this in the run() method of my Application (Kotlin):
environment.applicationContext.apply {
setAttribute(MetricsServlet.METRICS_REGISTRY, environment.metrics())
setAttribute(HealthCheckServlet.HEALTH_CHECK_REGISTRY, environment.healthChecks())
addServlet(NonblockingServletHolder(AdminServlet()), "/admin/*")
}
Then, I protect this path with a BasicAuthFilter (still Kotlin, you should use it):
val basicAuthFilter = BasicAuthFilter("admin", configuration.adminUsername, configuration.adminPassword)
val adminFilter = environment.servlets().addFilter("AdminFilter", basicAuthFilter)
adminFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/admin/*")
Related
I am trying to create policies using serverless framework. The idea is to access S3 services, depending on the user's company.
I tried to deploy my serverless.yaml with the policy:
- PolicyName: IAM_AWS_S3
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: '*'
Resource:
- !Sub 'arn:aws:s3:${AWS::AccountId}-${aws:PrincipalTag/company}'
- !Sub 'arn:aws:s3:${AWS::AccountId}-${aws:PrincipalTag/company}/*'
but I get this error:
CREATE_FAILED: AuthenticatedRole (AWS::IAM::Role) The policy failed
legacy parsing (Service: AmazonIdentityManagement; Status Code: 400;
Error Code: MalformedPolicyDocument; Request ID:
da38iiii; Proxy: null)
So, here is my question, is it possible to create a policy before I have a user? can PrincipalTag/company be null?
Thanks in advance
It is not possible to use PropertyTag for this issue due to I needed to use it in DynamoDB too.
I just create the policies through a Lambda.
Take into account these answers:
IAM Policy with `aws:ResourceTag` not supported
Use tags inside IAM policy resource
My application requires the app to run in https since the browser sends payment data to payment gateway through javascript library.
If the app is run in http then this error is thrown by the payment gateway.
I have created a simple hello world app and wrote a simple geb spec.
I dont seem to find a way to run the server in https mode. I dont find any helpful resource in the web as well.
Right now it is running in http mode in random port
Grails application running at http://localhost:54461 in environment: test
I have tried adding https port in build.gradle as
integrationTest {
systemProperty "webdriver.chrome.driver", "C:\\webdrivers\\chromedriver.exe"
jvmArgs(
'-Dgrails.server.port.https=8443'
)
}
But that seems to get ignored.
I have also tried setting the https port in intellij run configuration as shown below.
I have published the app code in github for reference.
https://github.com/learningcscience/gebhttps
I appreciate any help. Thanks!
UPDATE:
Today i think i made a little more progress.
I could now run the app in a fixed port. I ran the app in 8443 which is for https.
I did this using the spring boot test annotation
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
In the console now it shows
Grails application running at http://localhost:8443 in environment: test
Starting ChromeDriver 100.0.4896.20 (f9d71f93d32a6487809d6f35a9670c879fe97dfe-refs/branch-heads/4896#{#203}) on port 31898
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
https://docs.grails.org/latest/guide/testing.html
Now i just need to make the app run using the https rather than http.
I have updated the code in github repo.
https://github.com/learningcscience/gebhttps
I appreciate any help! Thanks!
ok. The problem is finally solved.
The last help came from the grails community at https://grails.slack.com/
Thanks Mattias Reichel for the help.
I am now going to put step by step process so that others might not get stuck with this issue.
In order to run functional geb test in https you first need to put SpringBootTest annotation as mentioned in above UPDATE: section.
I am pasting here again
#Integration
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class EventCreationSpec extends GebSpec {
After that you set baseurl in src/integration-test/resources/GebConfig.groovy.
I put baseUrl = "https://localhost:8443/"
My GebConfig looks like this
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
import org.openqa.selenium.firefox.FirefoxDriver
environments {
// run via “./gradlew -Dgeb.env=chrome iT”
chrome {
driver = {
System.setProperty('webdriver.chrome.driver', 'C:\\webdrivers\\chromedriver.exe')
new ChromeDriver()
}
}
// run via “./gradlew -Dgeb.env=chromeHeadless iT”
chromeHeadless {
driver = {
ChromeOptions o = new ChromeOptions()
o.addArguments('headless')
new ChromeDriver(o)
}
}
// run via “./gradlew -Dgeb.env=firefox iT”
firefox {
driver = { new FirefoxDriver() }
}
}
baseUrl = "https://localhost:8443/"
After that you need to create a application-test.yml file in src/integration-test/resources/
The application-test.yml file looks like this
server:
port: 8443
ssl:
enabled: true
keyStore: c:/Users/user/selfsigned.jks
keyStorePassword: pepsicola
keyAlias: tomcat
you need to create self signed certificate.
You can go through this process to create the certificate
https://grails.org/blog/2017-06-28.html
In the configuration above
my certificate was in selfsigned.jks keystore in the path c:/Users/user/selfsigned.jks
After that the functional test will fire in https mode
In my case
http://localhost:8443/roadrace
here is what the gebspec should look like
Note the SpringBootTest annotation at the top.
#Integration
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
#Stepwise
class EventCreationSpec extends GebSpec {
def grailsApplication
def springSecurityService
def timeService
def setup() {
}
def cleanup() {
}
void "Create and publish event"() {
when:"The home page is visited"
go '/roadrace/'
$("#details-button").click()
$("#proceed-link").click()
... rest of gebspock test steps....
then:"The title is correct"
title == "Homepage"
}
}
Please note that i had to go to /roadrace/ because the roadrace is the app context path.
If you dont have context path you can go to go '/'
The final hurdle can be when the browser fires up in https it might show
For this using geb you can click on the Advanced and then Proceed to localhost (unsafe) links
I just click the links like this
go '/roadrace/'
$("#details-button").click()
$("#proceed-link").click()
That's all! Now the geb functional test runs in https. Since it is https you can also now communicate to test payment gateway.
No matter what i do i can't connect to a mqtt broker via websocket in my angular application (trying in chrome and firefox).
For simplicity i'm using HiveMQ broker, i've published on the topic /gat/38/openReservationRequests some data
I've followed this medium article on how to connect to mqtt in angular using ngx-mqtt but for me it is not working.
In my app:
I've installed the module
npm install ngx-mqtt --save
i've added the configuration and set the module forRoot in my app.module.ts
...
export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
connectOnCreate: true,
hostname: 'broker.hivemq.com',
port: 8000,
path: '/gat/38/openReservationRequests',
protocol: 'ws',
};
...
imports: [
...
MqttModule.forRoot(MQTT_SERVICE_OPTIONS),
...
],
...
i'm executing this function inside the ngOnInit of app.component.ts
...
import { IMqttMessage, MqttConnectionState, MqttService } from 'ngx-mqtt';
...
constructor(private mqttService: MqttService) {
this.mqttService.state.subscribe((s: MqttConnectionState) => {
const status = s === MqttConnectionState.CONNECTED ? 'CONNECTED' : 'DISCONNECTED';
this.status.push(`Mqtt client connection status: ${status}`);
});
}
ngOnInit() {
this.subscription = this.mqttService
.observe('/gat/38/openReservationRequests')
.subscribe((message: IMqttMessage) => {
this.msg = message;
console.log('msg: ', message);
console.log('Message: ' + message.payload.toString() + 'for topic: ' + message.topic);
console.log('subscribed to topic: ' + /gat/38/openReservationRequests);
});
}
but i am always getting this error:
core.js:6014 ERROR TypeError: Cannot read property 'resubscribe' of undefined
at MqttClient.subscribe (mqtt.min.js:1)
at mqtt.service.js:211
at Observable._subscribe (using.js:8)
at Observable._trySubscribe (Observable.js:42)
at Observable.subscribe (Observable.js:28)
at FilterOperator.call (filter.js:13)
at Observable.subscribe (Observable.js:23)
at Observable.connect (ConnectableObservable.js:30)
at RefCountOperator.call (refCount.js:17)
at Observable.subscribe (Observable.js:23)
mqtt.min.js:1 WebSocket connection to 'ws://broker.hivemq.com:8000/gat/38/openReservationRequests' failed: Connection closed before receiving a handshake response
if i specify the clientId inside the MQTT_SERVICE_OPTIONS i still get the same error.
if i change the protocol to wss i get a different error:
core.js:6014 ERROR TypeError: Cannot read property 'resubscribe' of undefined
at MqttClient.subscribe (mqtt.min.js:1)
at mqtt.service.js:211
at Observable._subscribe (using.js:8)
at Observable._trySubscribe (Observable.js:42)
at Observable.subscribe (Observable.js:28)
at FilterOperator.call (filter.js:13)
at Observable.subscribe (Observable.js:23)
at Observable.connect (ConnectableObservable.js:30)
at RefCountOperator.call (refCount.js:17)
at Observable.subscribe (Observable.js:23)
mqtt.min.js:1 WebSocket connection to 'wss://broker.hivemq.com:8000/gat/38/openReservationRequests' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED
If i try to connect manually inside my app.component.ts ngOnInit before observing the topic:
this.mqttService.connect({
hostname: 'broker.hivemq.com',
port: 8000,
path: '/gat/38/openReservationRequests',
clientId: '34er23qwrfq42w3' //those are just random digits
});
i still get the error above.
For me it would be ideal to connect in some inner component (accessible after the user is authenticated) because i will have my private mqtt broker and the topic will depend on the logged user information.
I've tried any combination of protocol with/without cliendId etc but at this point i don't know what is wrong. I've already fully recompiled my app lots of times, i've tried publishing it on my test-server which has a ssl certificate but nothing changed.
Resolved thanks to #Anant Lalchandani i set the correct path.
The other problem was that '/mytopic' and 'mytopic' are indeed two different topic and i was using it wrong too.
This is my code, updated:
app.module.ts
export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
connectOnCreate: false,
hostname: 'broker.hivemq.com',
port: 8000,
path: '/mqtt'
};
appcomponent.ts (inside ngOnInit for now)
this.mqttService.connect({
hostname: 'broker.hivemq.com',
port: 8000,
path: '/mqtt',
clientId: '1234e3qer23rf'
});
this.mqttService.onConnect
.subscribe(
connack=> {
console.log('CONNECTED');
console.log(connack);
}
);
this.mqttService.observe('gat/38/openReservationRequests')
.subscribe((message: IMqttMessage) => {
this.msg = message;
console.log(new TextDecoder('utf-8').decode(message.payload));
});
I have checked the code snippets you shared in question.
In your app.module.ts, the path value should be '/mqtt'. You have set the topic as the value of path here. The topic can only be subscribed/published. As you are using a topic as a path value at the time of connecting to a websocket, your application will not be able to connect to websocket at the first place.
The reason why we need to use /mqtt as a path is it specifies you are sending MQTT messages over the WebSocket protocol.
The documentation of HiveMQ itself stated to use the path as '/mqtt' in its example. You can check the documentation here.
I'm in the midst of testing mod_http_api to replace the existing usage of mod_rest in our implementation.
I can unrestrict access to some commands from group of IP addresses by using option "admin_ip_access". I can successfully execute some commands (e.g. change_password).
However, for some cases, we may require login as well for both user (own)and admin(own and other user).
However, when I tried to login with Basic Auth. It's not successful. I'm keep on getting the following. If my assumption is correct, this might be related to configuration.
Will be much appreciated if someone could show me how the correct configuration should be done.
{
"status": "error",
"code": 31,
"message": "Command need to be run with admin priviledge."
}
Current config
modules:
mod_http_api:
admin_ip_access: admin_ip_access_rule
acl:
admin_ip_acl:
ip:
- "xx.xx.xx.xx/32"
access:
admin_ip_access_rule:
admin_ip_acl:
- all
EDIT
For testing purpose, I've enabled the following configuration:
commands_admin_access: configure
commands:
- add_commands:
- status
- get_roster
- change_password
- register
- unregister
- registered_users
- muc_online_rooms
- oauth_issue_token
I able to run both of user and admin commands successfully for those listed commands inside add_commands tags. It works as expected. However, I still facing some issues, most related to the IP restriction. Calling the API from the host that is not listed in admin_ip_acl also successful where I expect to get error when calling for non-whitelited host
The API requires an OAuth token for authentication. You need to generate one with correct scope. When a command is restricted to an admin, you need to also pass the HTTP header: "X-Admin: true" to let ejabberd know that it should consider you would like to act as an admin.
I am trying to integrate grails events-push plugin to push events to browser however its not working. I made below changes for it
BuildConfig.groovy
grails.tomcat.nio = true
compile ":events-push:1.0.M7"
Config.groovy
events.push.servlet.initParams = [
'org.atmosphere.cpr.cometSupport': 'org.atmosphere.container.Tomcat7CometSupport',
"org.atmosphere.cpr.CometSupport.maxInactiveActivity": "100000"
]
tomcat.nio=true
Deleted context.xml(generated by plugin) from META-INF folder as tomcat was not working with it
In Client side i.e angular js
window.grailsEvents = new grails.Events('http://localhost:8080');
I managed to start my application successfully. I also below message in log
DEBUG cpr.DefaultBroadcaster - Broadcaster eventsbus doesn't have any associated resource. Message will be cached in the configured BroadcasterCache
Bu when I open my application in browser websocket do not work.
In serve end I see below meesage
2014-05-01 15:19:56,365 [http-nio-8080-exec-3] DEBUG cpr.AsynchronousProcessor - Timing out the connection for request AtmosphereRequest{ contextPath= servletPath=/g-eventsbus pathInfo=/eventsbus requestURI=/g-eventsbus/eventsbus requestURL=http://localhost:8080/g-eventsbus/eventsbus destroyable=false}
2014-05-01 15:19:56,366 [http-nio-8080-exec-3] WARN websocket.DefaultWebSocketProcessor - Unable to retrieve AtmosphereResource for org.apache.catalina.websocket.WsOutbound#269dd750
2014-05-01 15:19:57,783 [http-nio-8080-exec-5] DEBUG cpr.AsynchronousProcessor - Timing out the connection for request AtmosphereRequest{ contextPath= servletPath=/g-eventsbus pathInfo=/eventsbus requestURI=/g-eventsbus/eventsbus requestURL=http://localhost:8080/g-eventsbus/eventsbus destroyable=false}
I browser console end I see
WebSocket connection to 'ws://localhost:8080/g-eventsbus/eventsbus?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=1.1.0.beta3&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true&X-Cache-Date=0&topics=eventsbus' failed: WebSocket is closed before the connection is established.
Guys please help me I am struggling with this plugin from long time.
I'm using grails-events-push and almost everything works well.
In BuildConfig:
grails.servlet.version = "3.0"
grails.tomcat.nio=true
...
dependencies {
...
compile 'org.grails.plugins:events:1.0.0.BUILD-SNAPSHOT'
compile 'org.atmosphere:atmosphere-runtime:2.1.4'
}
plugins {
...
build ":tomcat:7.0.52.1"
runtime ":events-push:1.0.0.BUILD-SNAPSHOT"
}
You have to create one file to declare your events: mine is EasyRestaurantEvents.groovy
import static reactor.event.selector.Selectors.*
includes = ['push']
doWithReactor = {
reactor('grailsReactor'){
ext 'browser', [
(R('oneMessage-([0-9]+)')) : true
]
}
reactor('browser'){
ext 'browser', [
'oneMessageFromBrowser' : true
]
}
}
In the controller or service I can send an event in this way:
event('oneMessage-' + someId, mapObject)
In the client app I can receive this message in this way:
grailsEvents.on("oneMessage-666",
function(event){
alert("oneMessage was received for client 666");
});
In the server app, I can receive a message from the browser, in this way:
import reactor.spring.annotation.ReplyTo
import reactor.spring.annotation.Selector
class OneService {
#Selector(reactor = 'browser')
#ReplyTo
def oneMessageFromBrowser(Map data){
//do some work
}
}
To send an event from the browser yo can do:
grailsEvents.send('oneMessageFromBrowser', {message:'hello from browser'});
I hope this helps! I struggled with this plugin a lot! =(
But is very easy to use (when you make it work)
PS: I used another application created in angular to communicate with the server so I have to import the js manually:
"atmosphere.js": 2.1.5-javascript
"jquery.atmosphere.js": 2.1.5-jquery
Thanks mpccolorado for you reply. I got it working actually issue was in JS grails.Events should be created with globalTopicName.
var grailsEvents = new grails.Events(GRAILS_EVENT_URL, {globalTopicName: 'newReview'});