aboutsummaryrefslogtreecommitdiff
path: root/doc/todo/cas_authentication.mdwn
blob: ed8010518ba8d15e228d5f16b0310b72a2eb5cba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
[[!tag patch wishlist]]

ikiwiki should support [Central Authentication
Service](http://www.ja-sig.org/products/cas/) authentication in order to use
this <acronym title='Single Sign On'>SSO</acronym> mechanism very popular in
universities web services.

I have already written a first draft plugin supporting that authentication
mechanism. It works for me with my university CAS service. I did not try it
with other CAS server but it do not see any reason why it should not work.

What is the best way to submit it to you (just in case it can help my patch
follows) ?

--[[/users/bbb]]

> Inline here is ok; git-am by mail is ok; a git repo I can pull from also
> ok.
> 
> This looks pretty acceptable as-is, but you need to put a copyright and
> license statement at the top. I have a few questions that I'll insert
> inline with the patch below. --[[Joey]]

>> I have made some corrections to this patch (my cas plugin) in order to use
>> IkiWiki 3.00 interface and take your comments into account. It should work
>> fine now.
>>
>> You can pull it from my git repo at
>> http://git.boulgour.com/bbb/ikiwiki.git/ and maybe add it to your main
>> repo.
>> 
>> I will add GNU GPL copyright license statement as soon as I get some free
>> time.
>>
>> --[[/users/bbb]]

------------------------------------------------------------------------------
    diff --git a/IkiWiki/Plugin/cas.pm b/IkiWiki/Plugin/cas.pm
    new file mode 100644
    index 0000000..ea189df
    --- /dev/null
    +++ b/IkiWiki/Plugin/cas.pm
    @@ -0,0 +1,94 @@
    +#!/usr/bin/perl
    +# JaSIG CAS support by Bruno Beaufils <bruno@boulgour.com>
    +package IkiWiki::Plugin::cas;
    +
    +use warnings;
    +use strict;
    +use IkiWiki 2.00;
    +use AuthCAS;                  # http://search.cpan.org/~osalaun/AuthCAS-1.3.1/

> In ikiwiki we generally deman-load perl modules only when they're used.
> This avoids loading expensive modules when the CGI isn't doing
> authentication. Can you do that with AuthCAS? Something like this before
> the use of it: `eval q{use AuthCAS}; error $@ if $@`

    +
    +sub import {
    +    hook(type => "getopt", id => "cas", call => \&getopt);
    +    hook(type => "auth", id => "cas", call => \&auth);
    +    hook(type => "formbuilder_setup", id => "cas", call => \&formbuilder_setup);
    +}

> Could you please use tabs for indentation of program flow?

    +# FIXME: We should check_config to ensure that :
    +# * cas_url and ca_file are present

> Please fix that..

    +# * no other auth plugin are present (at least passwordauth and openid)

> Why would you want to make other auth plugins not work? Could a site not
> legitimatly chose to use this and another auth method?

    +sub getopt () {
    +    eval q{use Getopt::Long};
    +    error($@) if $@;
    +    Getopt::Long::Configure('pass_through');
    +    GetOptions("cas_url=s" => \$config{cas_url});
    +    GetOptions("ca_file=s" => \$config{ca_file});
    +}
    +
    +sub auth ($$) {
    +    my $q=shift;
    +    my $session=shift;
    +
    +    my $cas = new AuthCAS(casUrl => $config{'cas'}{'cas_url'},
    +                          CAFile => $config{'cas'}{'ca_file'});
    +
    +    my $service = $config{'cgiurl'};
    +    my $ticket = $q->param('ticket');
    +
    +    unless (defined($ticket)) {
    +        $service .= "?$ENV{QUERY_STRING}";
    +        my $login_url = $cas->getServerLoginURL($service);
    +        debug("CAS: asking a Service Ticket for service $service");
    +        IkiWiki::redirect($q, $login_url);
    +        exit 0;
    +    } else {
    +        $service = $service . "?$ENV{QUERY_STRING}";
    +        $service =~ s/\&ticket=$ticket//;
    +        my $user = $cas->validateST($service, $ticket);
    +        if (defined $user) {
    +            debug("CAS: validating a Service Ticket ($ticket) for service $service");
    +            $session->param(name=>$user);
    +            $session->param(CASservice=>$service);
    +            IkiWiki::cgi_savesession($session);
    +        } else {
    +            error("CAS failure: ".&AuthCAS::get_errors());
    +        }
    +    }
    +}
    +
    +# I use formbuilder_setup and not formbuilder type in order to bypass the
    +# Logout processing done in IkiWiki::CGI::cgi_prefs()
    +sub formbuilder_setup (@) {
    +    my %params=@_;
    +    
    +    my $form=$params{form};
    +    my $session=$params{session};
    +    my $cgi=$params{cgi};
    +    my $buttons=$params{buttons};
    +
    +    my $cas = new AuthCAS(casUrl => $config{'cas'}{'cas_url'},
    +                          CAFile => $config{'cas'}{'ca_file'});
    +
    +    if ($form->title eq "preferences") {
    +        # Show the login
    +        if (! defined $form->field(name => "name")) {
    +            $form->field(name => "CAS ID",
    +                         disabled => 1,
    +                         value => $session->param("name"), 
    +                         size => 50,
    +                         force => 1,
    +                         fieldset => "login");
    +        }
    +        
    +        # Force a logout if asked
    +        if ($form->submitted && $form->submitted eq 'Logout')
    +        {
    +            debug("CAS: asking to remove the Ticket Grant Cookie");
    +            IkiWiki::redirect($cgi, $cas->getServerLogoutURL($config{'url'}));
    +            $session->delete();
    +            exit 0;
    +        }
    +    }
    +}
    +
    +1
    diff --git a/doc/plugins/cas.mdwn b/doc/plugins/cas.mdwn
    new file mode 100644
    index 0000000..2f2f53e
    --- /dev/null
    +++ b/doc/plugins/cas.mdwn
    @@ -0,0 +1,18 @@
    +[[ template id=plugin name=cas core=0 author="[[bbb]]"]]
    +[[ tag type/auth]]
    +
    +This plugin allows users to use authentication offered by a
    +[JaSIG](http://www.ja-sig.org) [<acronym title='Central Authentication
    +Service'>CAS</acronym>](http://www.ja-sig.org/products/cas/) server to log
    +into the wiki.
    +
    +The plugin needs the [[!cpan AuthCAS-1.3.1]] perl module.

> Does it really need that specific version? I think you should lose the
> version part.

    +
    +This plugin has two mandatory configuration option. You **must** set `--cas_url`
    +to the url of a server offering CAS 2.0 authentication. You must also set the
    +`--ca_file` to an absolute path to the file containing CA certificates used by
    +the server (generally, aka under Debian, fixing that value to
    +`/etc/ssl/certs/ca-certificates.crt` is sufficient).

> It would be good to add commented-out examples of these to
> ikiwiki.setup as well.

    +This plugin is not enabled by default. It can not be used with other
    +authentication plugin, such as [[passwordauth]] or [[openid]].

------------------------------------------------------------------------------