17 views
Skip to first unread message

Miguelangel Fernandez

unread,
Dec 21, 2017, 7:49:36 AM12/21/17
to jenkin...@googlegroups.com
Hi everyone,

I've written a Jenkins plugin to implement my own authentication mechanism by extending hudson.security.SecurityRealm. Now I'm trying to create my own custom "Access Denied" page, to display when a user types in the wrong password or simply doesn't have access. To do this, I've created a file called accessDenied.jelly. So let's say the name of my company is "Foo" and the structure of my plugin (simplified here for practical reasons) is this:

src
|---main
    |---java
    |   |---com
    |       |---foo
    |           |---authn
    |               |---MySecurityRealm.java
    |---resources
    |   |---com
    |       |---foo
    |           |---authn
    |               |---MySecurityRealm
    |                   |---config.jelly
    |                   |---accessDenied.jelly
    |---webapp
        |---images
            |---foo.png

Now, I want to display my company logo -The foo.png file in the tree above- in my custom error page accessDenied.jelly. Again, for the sake of simplicity let's assume the short name of my plugin is simply foo and this is the content of accessDenied.jelly:

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
    <l:layout title="${%Login Error}" permission="${app.ANONYMOUS}">
        <l:main-panel>
            <h2>Access Denied</h2>
            <span class="message">
                You don't have access to this Jenkins console.
            </span>
            <img src="${app.getRootUrl()}plugin/foo/images/foo.png"/>
        </l:main-panel>
    </l:layout>
</j:jelly>

My problem here is I'm getting a broken image link for foo.png because the server returns a HTTP 403 Forbidden on serving it. Implying the user must be authenticated in order to access the static content in a plugin.

If instead of my company logo I use ${app.getRootUrl()}/favicon.ico for the source of my image, I do get the Jenkins icon displayed.

How can I make the static content in my plugin accessible without authentication? or public?

Notice I tried setting permission="${app.ANONYMOUS}" in my Jelly file, but this refers to the view being rendered, not to any static assets referenced by it.

If anyone would like the extra rep points in StackOverflow, I've posted the exact same question here:

https://stackoverflow.com/q/47830458/4124574

Thank you,

                                              Miguelángel Fernández M.

Life is what happens to you while you're busy making other plans.

                                                                                    --John Lennon.

Daniel Beck

unread,
Dec 21, 2017, 9:33:09 AM12/21/17
to jenkin...@googlegroups.com

> On 21. Dec 2017, at 13:49, Miguelangel Fernandez <miguela...@gmail.com> wrote:
>
> How can I make the static content in my plugin accessible without authentication? or public?

Only specific URLs are allowed to be accessed without Overall/Read permission, and arbitrary resource files from plugins aren't. One of the URLs that work is /securityRealm, so the currently selected security realm is exposed, allowing users without any permissions to interact with the security realm. That means you can add a getter or similar with some wiring that serves your resource file programmatically.

When put next to the views of the security realm, the following addition to MySecurityRealm will serve the file at /securityRealm/logo
---
public void doLogo(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
URL resource = MySecurityRealm.class.getResource("MySecurityRealm/logo.png");
rsp.serveFile(req, resource);
}
---

Jesse Glick

unread,
Dec 21, 2017, 10:35:46 AM12/21/17
to Jenkins Dev
On Thu, Dec 21, 2017 at 7:49 AM, Miguelangel Fernandez
<miguela...@gmail.com> wrote:
> I've written a Jenkins plugin to implement my own authentication mechanism
> by extending hudson.security.SecurityRealm. Now I'm trying to create my own
> custom "Access Denied" page

FWIW I do not recommend you even attempt this. Implement a simple
`AbstractPasswordBasedSecurityRealm` (in the unlikely event there is
not already one able to connect to your backend authentication system)
and leave it at that.

Miguelangel Fernandez

unread,
Dec 22, 2017, 4:26:09 AM12/22/17
to Jenkins Developers
Thank you @Daniel. Great answer. This solves my problem.
Reply all
Reply to author
Forward
0 new messages